From 3c223b22a2ea474ad6b11eff8ad40e80351b6df4 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 4 Jan 2017 10:02:45 +0700 Subject: [PATCH 1/2] include peer perspective in nullAEAD ref #375 --- crypto/null_aead.go | 37 +++++++++++++++--- crypto/null_aead_test.go | 64 +++++++++++++++++++++----------- handshake/crypto_setup_client.go | 7 ++-- handshake/crypto_setup_server.go | 7 ++-- packet_unpacker_test.go | 6 ++- protocol/version.go | 1 + server_test.go | 6 ++- session_test.go | 2 +- 8 files changed, 93 insertions(+), 37 deletions(-) diff --git a/crypto/null_aead.go b/crypto/null_aead.go index 5aa198ce..ed856633 100644 --- a/crypto/null_aead.go +++ b/crypto/null_aead.go @@ -8,13 +8,24 @@ import ( "github.com/lucas-clemente/quic-go/protocol" ) -// NullAEAD handles not-yet encrypted packets -type NullAEAD struct{} +// nullAEAD handles not-yet encrypted packets +type nullAEAD struct { + perspective protocol.Perspective + version protocol.VersionNumber +} -var _ AEAD = &NullAEAD{} +var _ AEAD = &nullAEAD{} + +// NewNullAEAD creates a NullAEAD +func NewNullAEAD(p protocol.Perspective, v protocol.VersionNumber) AEAD { + return &nullAEAD{ + perspective: p, + version: v, + } +} // Open and verify the ciphertext -func (NullAEAD) Open(dst, src []byte, packetNumber protocol.PacketNumber, associatedData []byte) ([]byte, error) { +func (n *nullAEAD) Open(dst, src []byte, packetNumber protocol.PacketNumber, associatedData []byte) ([]byte, error) { if len(src) < 12 { return nil, errors.New("NullAEAD: ciphertext cannot be less than 12 bytes long") } @@ -22,6 +33,13 @@ func (NullAEAD) Open(dst, src []byte, packetNumber protocol.PacketNumber, associ hash := fnv128a.New() hash.Write(associatedData) hash.Write(src[12:]) + if n.version >= protocol.Version37 { + if n.perspective == protocol.PerspectiveServer { + hash.Write([]byte("Client")) + } else { + hash.Write([]byte("Server")) + } + } testHigh, testLow := hash.Sum128() low := binary.LittleEndian.Uint64(src) @@ -34,7 +52,7 @@ func (NullAEAD) Open(dst, src []byte, packetNumber protocol.PacketNumber, associ } // Seal writes hash and ciphertext to the buffer -func (NullAEAD) Seal(dst, src []byte, packetNumber protocol.PacketNumber, associatedData []byte) []byte { +func (n *nullAEAD) Seal(dst, src []byte, packetNumber protocol.PacketNumber, associatedData []byte) []byte { if cap(dst) < 12+len(src) { dst = make([]byte, 12+len(src)) } else { @@ -44,6 +62,15 @@ func (NullAEAD) Seal(dst, src []byte, packetNumber protocol.PacketNumber, associ hash := fnv128a.New() hash.Write(associatedData) hash.Write(src) + + if n.version >= protocol.Version37 { + if n.perspective == protocol.PerspectiveServer { + hash.Write([]byte("Server")) + } else { + hash.Write([]byte("Client")) + } + } + high, low := hash.Sum128() copy(dst[12:], src) diff --git a/crypto/null_aead_test.go b/crypto/null_aead_test.go index 14be9f4f..144715a6 100644 --- a/crypto/null_aead_test.go +++ b/crypto/null_aead_test.go @@ -1,46 +1,37 @@ package crypto import ( + "github.com/lucas-clemente/quic-go/protocol" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("Crypto/NullAEAD", func() { + aad := []byte("All human beings are born free and equal in dignity and rights.") + plainText := []byte("They are endowed with reason and conscience and should act towards one another in a spirit of brotherhood.") + hash36 := []byte{0x98, 0x9b, 0x33, 0x3f, 0xe8, 0xde, 0x32, 0x5c, 0xa6, 0x7f, 0x9c, 0xf7} + It("opens", func() { - aad := []byte("All human beings are born free and equal in dignity and rights.") - plainText := []byte("They are endowed with reason and conscience and should act towards one another in a spirit of brotherhood.") - hash := []byte{0x98, 0x9b, 0x33, 0x3f, 0xe8, 0xde, 0x32, 0x5c, 0xa6, 0x7f, 0x9c, 0xf7} - cipherText := append(hash, plainText...) - aead := &NullAEAD{} + cipherText := append(hash36, plainText...) + aead := NewNullAEAD(protocol.PerspectiveServer, protocol.Version36) res, err := aead.Open(nil, cipherText, 0, aad) Expect(err).ToNot(HaveOccurred()) Expect(res).To(Equal([]byte("They are endowed with reason and conscience and should act towards one another in a spirit of brotherhood."))) }) - It("fails", func() { - aad := []byte("All human beings are born free and equal in dignity and rights..") - plainText := []byte("They are endowed with reason and conscience and should act towards one another in a spirit of brotherhood.") - hash := []byte{0x98, 0x9b, 0x33, 0x3f, 0xe8, 0xde, 0x32, 0x5c, 0xa6, 0x7f, 0x9c, 0xf7} - cipherText := append(hash, plainText...) - aead := &NullAEAD{} - _, err := aead.Open(nil, cipherText, 0, aad) - Expect(err).To(HaveOccurred()) - }) - It("seals", func() { - aad := []byte("All human beings are born free and equal in dignity and rights.") - plainText := []byte("They are endowed with reason and conscience and should act towards one another in a spirit of brotherhood.") - aead := &NullAEAD{} - Expect(aead.Seal(nil, plainText, 0, aad)).To(Equal(append([]byte{0x98, 0x9b, 0x33, 0x3f, 0xe8, 0xde, 0x32, 0x5c, 0xa6, 0x7f, 0x9c, 0xf7}, []byte("They are endowed with reason and conscience and should act towards one another in a spirit of brotherhood.")...))) + aead := NewNullAEAD(protocol.PerspectiveServer, protocol.Version36) + Expect(aead.Seal(nil, plainText, 0, aad)).To(Equal(append(hash36, []byte("They are endowed with reason and conscience and should act towards one another in a spirit of brotherhood.")...))) }) It("rejects short ciphertexts", func() { - _, err := NullAEAD{}.Open(nil, nil, 0, nil) + aead := NewNullAEAD(protocol.PerspectiveServer, protocol.Version36) + _, err := aead.Open(nil, nil, 0, nil) Expect(err).To(MatchError("NullAEAD: ciphertext cannot be less than 12 bytes long")) }) It("seals in-place", func() { - aead := &NullAEAD{} + aead := NewNullAEAD(protocol.PerspectiveServer, protocol.Version36) buf := make([]byte, 6, 12+6) copy(buf, []byte("foobar")) res := aead.Seal(buf[0:0], buf, 0, nil) @@ -48,4 +39,35 @@ var _ = Describe("Crypto/NullAEAD", func() { Expect(buf[12:]).To(Equal([]byte("foobar"))) Expect(res[12:]).To(Equal([]byte("foobar"))) }) + + It("fails", func() { + cipherText := append(append(hash36, plainText...), byte(0x42)) + aead := NewNullAEAD(protocol.PerspectiveServer, protocol.Version36) + _, err := aead.Open(nil, cipherText, 0, aad) + Expect(err).To(HaveOccurred()) + }) + + Context("including the perspective, for QUIC >= 37", func() { + var aeadServer AEAD + var aeadClient AEAD + + BeforeEach(func() { + aeadServer = NewNullAEAD(protocol.PerspectiveServer, protocol.Version37) + aeadClient = NewNullAEAD(protocol.PerspectiveClient, protocol.Version37) + }) + + It("opens, for QUIC version >= 37, as a server", func() { + cipherText := aeadClient.Seal(nil, plainText, 0, aad) + res, err := aeadServer.Open(nil, cipherText, 0, aad) + Expect(err).ToNot(HaveOccurred()) + Expect(res).To(Equal([]byte("They are endowed with reason and conscience and should act towards one another in a spirit of brotherhood."))) + }) + + It("opens, for QUIC version >= 37, as a client", func() { + cipherText := aeadServer.Seal(nil, plainText, 0, aad) + res, err := aeadClient.Open(nil, cipherText, 0, aad) + Expect(err).ToNot(HaveOccurred()) + Expect(res).To(Equal([]byte("They are endowed with reason and conscience and should act towards one another in a spirit of brotherhood."))) + }) + }) }) diff --git a/handshake/crypto_setup_client.go b/handshake/crypto_setup_client.go index 6aaeb5f8..c81fe997 100644 --- a/handshake/crypto_setup_client.go +++ b/handshake/crypto_setup_client.go @@ -44,6 +44,7 @@ type cryptoSetupClient struct { keyExchange KeyExchangeFunction receivedSecurePacket bool + nullAEAD crypto.AEAD secureAEAD crypto.AEAD forwardSecureAEAD crypto.AEAD aeadChanged chan protocol.EncryptionLevel @@ -79,6 +80,7 @@ func NewCryptoSetupClient( connectionParameters: connectionParameters, keyDerivation: crypto.DeriveKeysAESGCM, keyExchange: getEphermalKEX, + nullAEAD: crypto.NewNullAEAD(protocol.PerspectiveClient, version), aeadChanged: aeadChanged, negotiatedVersions: negotiatedVersions, }, nil @@ -300,8 +302,7 @@ func (h *cryptoSetupClient) Open(dst, src []byte, packetNumber protocol.PacketNu return nil, protocol.EncryptionUnspecified, err } } - nullAEAD := &crypto.NullAEAD{} - res, err := nullAEAD.Open(dst, src, packetNumber, associatedData) + res, err := h.nullAEAD.Open(dst, src, packetNumber, associatedData) if err != nil { return nil, protocol.EncryptionUnspecified, err } @@ -340,7 +341,7 @@ func (h *cryptoSetupClient) GetSealerWithEncryptionLevel(encLevel protocol.Encry } func (h *cryptoSetupClient) sealUnencrypted(dst, src []byte, packetNumber protocol.PacketNumber, associatedData []byte) []byte { - return (&crypto.NullAEAD{}).Seal(dst, src, packetNumber, associatedData) + return h.nullAEAD.Seal(dst, src, packetNumber, associatedData) } func (h *cryptoSetupClient) sealSecure(dst, src []byte, packetNumber protocol.PacketNumber, associatedData []byte) []byte { diff --git a/handshake/crypto_setup_server.go b/handshake/crypto_setup_server.go index 4740b09c..ada88053 100644 --- a/handshake/crypto_setup_server.go +++ b/handshake/crypto_setup_server.go @@ -28,6 +28,7 @@ type cryptoSetupServer struct { scfg *ServerConfig diversificationNonce []byte + nullAEAD crypto.AEAD secureAEAD crypto.AEAD forwardSecureAEAD crypto.AEAD receivedForwardSecurePacket bool @@ -69,6 +70,7 @@ func NewCryptoSetup( scfg: scfg, keyDerivation: crypto.DeriveKeysAESGCM, keyExchange: getEphermalKEX, + nullAEAD: crypto.NewNullAEAD(protocol.PerspectiveServer, version), cryptoStream: cryptoStream, connectionParameters: connectionParametersManager, aeadChanged: aeadChanged, @@ -184,8 +186,7 @@ func (h *cryptoSetupServer) Open(dst, src []byte, packetNumber protocol.PacketNu return nil, protocol.EncryptionUnspecified, err } } - nullAEAD := &crypto.NullAEAD{} - res, err := nullAEAD.Open(dst, src, packetNumber, associatedData) + res, err := h.nullAEAD.Open(dst, src, packetNumber, associatedData) if err != nil { return res, protocol.EncryptionUnspecified, err } @@ -225,7 +226,7 @@ func (h *cryptoSetupServer) GetSealerWithEncryptionLevel(encLevel protocol.Encry } func (h *cryptoSetupServer) sealUnencrypted(dst, src []byte, packetNumber protocol.PacketNumber, associatedData []byte) []byte { - return (&crypto.NullAEAD{}).Seal(dst, src, packetNumber, associatedData) + return h.nullAEAD.Seal(dst, src, packetNumber, associatedData) } func (h *cryptoSetupServer) sealSecure(dst, src []byte, packetNumber protocol.PacketNumber, associatedData []byte) []byte { diff --git a/packet_unpacker_test.go b/packet_unpacker_test.go index 90d4d083..b56ba2f4 100644 --- a/packet_unpacker_test.go +++ b/packet_unpacker_test.go @@ -17,11 +17,13 @@ type mockAEAD struct { } func (m *mockAEAD) Open(dst, src []byte, packetNumber protocol.PacketNumber, associatedData []byte) ([]byte, protocol.EncryptionLevel, error) { - res, err := (&crypto.NullAEAD{}).Open(dst, src, packetNumber, associatedData) + nullAEAD := crypto.NewNullAEAD(protocol.PerspectiveServer, protocol.VersionWhatever) + res, err := nullAEAD.Open(dst, src, packetNumber, associatedData) return res, m.encLevelOpen, err } func (m *mockAEAD) Seal(dst, src []byte, packetNumber protocol.PacketNumber, associatedData []byte) ([]byte, protocol.EncryptionLevel) { - return (&crypto.NullAEAD{}).Seal(dst, src, packetNumber, associatedData), protocol.EncryptionUnspecified + nullAEAD := crypto.NewNullAEAD(protocol.PerspectiveServer, protocol.VersionWhatever) + return nullAEAD.Seal(dst, src, packetNumber, associatedData), protocol.EncryptionUnspecified } var _ quicAEAD = &mockAEAD{} diff --git a/protocol/version.go b/protocol/version.go index d5c0dacf..424b5dd3 100644 --- a/protocol/version.go +++ b/protocol/version.go @@ -13,6 +13,7 @@ type VersionNumber int const ( Version35 VersionNumber = 35 + iota Version36 + Version37 VersionWhatever = 0 // for when the version doesn't matter VersionUnsupported = -1 ) diff --git a/server_test.go b/server_test.go index 5a575edd..06512d8d 100644 --- a/server_test.go +++ b/server_test.go @@ -169,7 +169,8 @@ var _ = Describe("Server", func() { It("closes and deletes sessions", func() { serv.deleteClosedSessionsAfter = time.Second // make sure that the nil value for the closed session doesn't get deleted in this test - err := serv.handlePacket(nil, nil, append(firstPacket, (&crypto.NullAEAD{}).Seal(nil, nil, 0, firstPacket)...)) + nullAEAD := crypto.NewNullAEAD(protocol.PerspectiveServer, protocol.VersionWhatever) + err := serv.handlePacket(nil, nil, append(firstPacket, nullAEAD.Seal(nil, nil, 0, firstPacket)...)) Expect(err).ToNot(HaveOccurred()) Expect(serv.sessions).To(HaveLen(1)) Expect(serv.sessions[connID]).ToNot(BeNil()) @@ -181,7 +182,8 @@ var _ = Describe("Server", func() { It("deletes nil session entries after a wait time", func() { serv.deleteClosedSessionsAfter = 25 * time.Millisecond - err := serv.handlePacket(nil, nil, append(firstPacket, (&crypto.NullAEAD{}).Seal(nil, nil, 0, firstPacket)...)) + nullAEAD := crypto.NewNullAEAD(protocol.PerspectiveServer, protocol.VersionWhatever) + err := serv.handlePacket(nil, nil, append(firstPacket, nullAEAD.Seal(nil, nil, 0, firstPacket)...)) Expect(err).ToNot(HaveOccurred()) Expect(serv.sessions).To(HaveLen(1)) serv.closeCallback(connID) diff --git a/session_test.go b/session_test.go index 8aff5cd5..419d825b 100644 --- a/session_test.go +++ b/session_test.go @@ -1343,7 +1343,7 @@ var _ = Describe("Session", func() { It("uses ICSL after handshake", func(done Done) { // sess.lastNetworkActivityTime = time.Now().Add(-time.Minute) *(*bool)(unsafe.Pointer(reflect.ValueOf(sess.cryptoSetup).Elem().FieldByName("receivedForwardSecurePacket").UnsafeAddr())) = true - *(*crypto.AEAD)(unsafe.Pointer(reflect.ValueOf(sess.cryptoSetup).Elem().FieldByName("forwardSecureAEAD").UnsafeAddr())) = &crypto.NullAEAD{} + *(*crypto.AEAD)(unsafe.Pointer(reflect.ValueOf(sess.cryptoSetup).Elem().FieldByName("forwardSecureAEAD").UnsafeAddr())) = crypto.NewNullAEAD(protocol.PerspectiveServer, protocol.VersionWhatever) cpm.idleTime = 0 * time.Millisecond sess.packer.connectionParameters = sess.connectionParameters sess.run() // Would normally not return From 0a2c37d42ae5ff2f041c9ddf08bdd8251f72253a Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 27 Apr 2017 18:32:28 +0700 Subject: [PATCH 2/2] add QUIC 37 to supported versions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fixes #375 Chrome tests are disabled for QUIC 37, since the Chrome version in the docker image doesn’t support this version yet. --- h2quic/server_test.go | 2 +- handshake/crypto_setup_server_test.go | 29 ++++++++++++++++----------- integrationtests/chrome_test.go | 10 ++++----- protocol/version.go | 2 +- protocol/version_test.go | 4 ++-- 5 files changed, 25 insertions(+), 22 deletions(-) diff --git a/h2quic/server_test.go b/h2quic/server_test.go index 1ebce584..6186d557 100644 --- a/h2quic/server_test.go +++ b/h2quic/server_test.go @@ -316,7 +316,7 @@ var _ = Describe("H2 server", func() { Context("setting http headers", func() { expected := http.Header{ - "Alt-Svc": {`quic=":443"; ma=2592000; v="36,35"`}, + "Alt-Svc": {`quic=":443"; ma=2592000; v="37,36,35"`}, "Alternate-Protocol": {`443:quic`}, } diff --git a/handshake/crypto_setup_server_test.go b/handshake/crypto_setup_server_test.go index 11a44f52..5f93edab 100644 --- a/handshake/crypto_setup_server_test.go +++ b/handshake/crypto_setup_server_test.go @@ -155,6 +155,7 @@ var _ = Describe("Crypto setup", func() { validSTK []byte aead []byte kexs []byte + version protocol.VersionNumber ) BeforeEach(func() { @@ -177,9 +178,9 @@ var _ = Describe("Crypto setup", func() { binary.LittleEndian.PutUint32(versionTag, protocol.VersionNumberToTag(protocol.VersionWhatever)) Expect(err).NotTo(HaveOccurred()) scfg.stkSource = &mockStkSource{} - v := protocol.SupportedVersions[len(protocol.SupportedVersions)-1] + version = protocol.SupportedVersions[len(protocol.SupportedVersions)-1] cpm = NewConnectionParamatersManager(protocol.PerspectiveServer, protocol.VersionWhatever) - csInt, err := NewCryptoSetup(protocol.ConnectionID(42), sourceAddr, v, scfg, stream, cpm, aeadChanged) + csInt, err := NewCryptoSetup(protocol.ConnectionID(42), sourceAddr, version, scfg, stream, cpm, aeadChanged) Expect(err).NotTo(HaveOccurred()) cs = csInt.(*cryptoSetupServer) cs.keyDerivation = mockKeyDerivation @@ -473,10 +474,14 @@ var _ = Describe("Crypto setup", func() { }) Context("escalating crypto", func() { - var foobarFNVSigned []byte + var foobarServerFNVSigned []byte // a "foobar" sent by the server, FNV signed + var foobarClientFNVSigned []byte // a "foobar" sent by the client, FNV signed BeforeEach(func() { - foobarFNVSigned = []byte{0x18, 0x6f, 0x44, 0xba, 0x97, 0x35, 0xd, 0x6f, 0xbf, 0x64, 0x3c, 0x79, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72} + nullAEADServer := crypto.NewNullAEAD(protocol.PerspectiveServer, version) + foobarServerFNVSigned = nullAEADServer.Seal(nil, []byte("foobar"), 0, []byte{}) + nullAEADClient := crypto.NewNullAEAD(protocol.PerspectiveClient, version) + foobarClientFNVSigned = nullAEADClient.Seal(nil, []byte("foobar"), 0, []byte{}) }) doCHLO := func() { @@ -494,19 +499,19 @@ var _ = Describe("Crypto setup", func() { enc, seal := cs.GetSealer() Expect(enc).To(Equal(protocol.EncryptionUnencrypted)) d := seal(nil, []byte("foobar"), 0, []byte{}) - Expect(d).To(Equal(foobarFNVSigned)) + Expect(d).To(Equal(foobarServerFNVSigned)) }) It("is accepted initially", func() { - d, enc, err := cs.Open(nil, foobarFNVSigned, 0, []byte{}) + d, enc, err := cs.Open(nil, foobarClientFNVSigned, 0, []byte{}) Expect(err).ToNot(HaveOccurred()) Expect(d).To(Equal([]byte("foobar"))) Expect(enc).To(Equal(protocol.EncryptionUnencrypted)) }) It("errors if the has the wrong hash", func() { - foobarFNVSigned[0]++ - _, enc, err := cs.Open(nil, foobarFNVSigned, 0, []byte{}) + foobarClientFNVSigned[0]++ + _, enc, err := cs.Open(nil, foobarClientFNVSigned, 0, []byte{}) Expect(err).To(MatchError("NullAEAD: failed to authenticate received data")) Expect(enc).To(Equal(protocol.EncryptionUnspecified)) }) @@ -514,7 +519,7 @@ var _ = Describe("Crypto setup", func() { It("is still accepted after CHLO", func() { doCHLO() Expect(cs.secureAEAD).ToNot(BeNil()) - _, enc, err := cs.Open(nil, foobarFNVSigned, 0, []byte{}) + _, enc, err := cs.Open(nil, foobarClientFNVSigned, 0, []byte{}) Expect(err).ToNot(HaveOccurred()) Expect(enc).To(Equal(protocol.EncryptionUnencrypted)) }) @@ -526,7 +531,7 @@ var _ = Describe("Crypto setup", func() { Expect(enc).To(Equal(protocol.EncryptionSecure)) Expect(err).ToNot(HaveOccurred()) Expect(d).To(Equal([]byte("decrypted"))) - _, enc, err = cs.Open(nil, foobarFNVSigned, 0, []byte{}) + _, enc, err = cs.Open(nil, foobarClientFNVSigned, 0, []byte{}) Expect(err).To(MatchError("authentication failed")) Expect(enc).To(Equal(protocol.EncryptionUnspecified)) }) @@ -536,7 +541,7 @@ var _ = Describe("Crypto setup", func() { enc, seal := cs.GetSealer() Expect(enc).ToNot(Equal(protocol.EncryptionUnencrypted)) d := seal(nil, []byte("foobar"), 0, []byte{}) - Expect(d).ToNot(Equal(foobarFNVSigned)) + Expect(d).ToNot(Equal(foobarServerFNVSigned)) }) }) @@ -598,7 +603,7 @@ var _ = Describe("Crypto setup", func() { seal, err := cs.GetSealerWithEncryptionLevel(protocol.EncryptionUnencrypted) Expect(err).ToNot(HaveOccurred()) d := seal(nil, []byte("foobar"), 0, []byte{}) - Expect(d).To(Equal(foobarFNVSigned)) + Expect(d).To(Equal(foobarServerFNVSigned)) }) It("forces initial encryption", func() { diff --git a/integrationtests/chrome_test.go b/integrationtests/chrome_test.go index d991b37d..e1f4ea77 100644 --- a/integrationtests/chrome_test.go +++ b/integrationtests/chrome_test.go @@ -45,12 +45,7 @@ func init() { var _ = Describe("Chrome tests", func() { It("does not work with mismatching versions", func() { versionForUs := protocol.SupportedVersions[0] - versionForChrome := protocol.SupportedVersions[len(protocol.SupportedVersions)-1] - - // If both are equal, this test doesn't make any sense. - if versionForChrome == versionForUs { - return - } + versionForChrome := protocol.SupportedVersions[1] supportedVersionsBefore := protocol.SupportedVersions protocol.SupportedVersions = []protocol.VersionNumber{versionForUs} @@ -78,6 +73,9 @@ var _ = Describe("Chrome tests", func() { ) BeforeEach(func() { + if version == protocol.Version37 { + Skip("Skipping Chrome test with QUIC version 37") + } supportedVersionsBefore = protocol.SupportedVersions protocol.SupportedVersions = []protocol.VersionNumber{version} wd = getWebdriverForVersion(version) diff --git a/protocol/version.go b/protocol/version.go index 424b5dd3..de5cbe79 100644 --- a/protocol/version.go +++ b/protocol/version.go @@ -21,7 +21,7 @@ const ( // SupportedVersions lists the versions that the server supports // must be in sorted order var SupportedVersions = []VersionNumber{ - Version35, Version36, + Version35, Version36, Version37, } // SupportedVersionsAsTags is needed for the SHLO crypto message diff --git a/protocol/version_test.go b/protocol/version_test.go index 3d3095f4..70820cf5 100644 --- a/protocol/version_test.go +++ b/protocol/version_test.go @@ -15,11 +15,11 @@ var _ = Describe("Version", func() { }) It("has proper tag list", func() { - Expect(SupportedVersionsAsTags).To(Equal([]byte("Q035Q036"))) + Expect(SupportedVersionsAsTags).To(Equal([]byte("Q035Q036Q037"))) }) It("has proper version list", func() { - Expect(SupportedVersionsAsString).To(Equal("36,35")) + Expect(SupportedVersionsAsString).To(Equal("37,36,35")) }) It("recognizes supported versions", func() {