diff --git a/internal/handshake/crypto_setup_test.go b/internal/handshake/crypto_setup_test.go index c2390fd6..9d52b801 100644 --- a/internal/handshake/crypto_setup_test.go +++ b/internal/handshake/crypto_setup_test.go @@ -271,6 +271,7 @@ var _ = Describe("Crypto Setup TLS", func() { Expect(err).ToNot(HaveOccurred()) sChunkChan, sInitialStream, sHandshakeStream := initStreams() + var token [16]byte server, err := NewCryptoSetupServer( sInitialStream, sHandshakeStream, @@ -279,7 +280,7 @@ var _ = Describe("Crypto Setup TLS", func() { &EncryptedExtensionsTransportParameters{ NegotiatedVersion: protocol.VersionTLS, SupportedVersions: []protocol.VersionNumber{protocol.VersionTLS}, - Parameters: TransportParameters{StatelessResetToken: bytes.Repeat([]byte{42}, 16)}, + Parameters: TransportParameters{StatelessResetToken: &token}, }, func([]byte) {}, serverConf, @@ -359,9 +360,10 @@ var _ = Describe("Crypto Setup TLS", func() { Expect(err).ToNot(HaveOccurred()) sChunkChan, sInitialStream, sHandshakeStream := initStreams() + var token [16]byte sTransportParameters := &TransportParameters{ IdleTimeout: 0x1337 * time.Second, - StatelessResetToken: bytes.Repeat([]byte{42}, 16), + StatelessResetToken: &token, } server, err := NewCryptoSetupServer( sInitialStream, diff --git a/internal/handshake/transport_parameter_test.go b/internal/handshake/transport_parameter_test.go index 7e3d9b46..0d665417 100644 --- a/internal/handshake/transport_parameter_test.go +++ b/internal/handshake/transport_parameter_test.go @@ -24,9 +24,9 @@ var _ = Describe("Transport Parameters", func() { IdleTimeout: 42 * time.Second, OriginalConnectionID: protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef}, AckDelayExponent: 14, - StatelessResetToken: []byte{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe}, + StatelessResetToken: &[16]byte{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00}, } - Expect(p.String()).To(Equal("&handshake.TransportParameters{OriginalConnectionID: 0xdeadbeef, InitialMaxStreamDataBidiLocal: 0x1234, InitialMaxStreamDataBidiRemote: 0x2345, InitialMaxStreamDataUni: 0x3456, InitialMaxData: 0x4567, MaxBidiStreams: 1337, MaxUniStreams: 7331, IdleTimeout: 42s, AckDelayExponent: 14, StatelessResetToken: 0xdeadbeefcafe}")) + Expect(p.String()).To(Equal("&handshake.TransportParameters{OriginalConnectionID: 0xdeadbeef, InitialMaxStreamDataBidiLocal: 0x1234, InitialMaxStreamDataBidiRemote: 0x2345, InitialMaxStreamDataUni: 0x3456, InitialMaxData: 0x4567, MaxBidiStreams: 1337, MaxUniStreams: 7331, IdleTimeout: 42s, AckDelayExponent: 14, StatelessResetToken: 0x112233445566778899aabbccddeeff00}")) }) getRandomValue := func() uint64 { @@ -36,6 +36,8 @@ var _ = Describe("Transport Parameters", func() { } It("marshals und unmarshals", func() { + var token [16]byte + rand.Read(token[:]) params := &TransportParameters{ InitialMaxStreamDataBidiLocal: protocol.ByteCount(getRandomValue()), InitialMaxStreamDataBidiRemote: protocol.ByteCount(getRandomValue()), @@ -45,7 +47,7 @@ var _ = Describe("Transport Parameters", func() { MaxBidiStreams: getRandomValue(), MaxUniStreams: getRandomValue(), DisableMigration: true, - StatelessResetToken: bytes.Repeat([]byte{100}, 16), + StatelessResetToken: &token, OriginalConnectionID: protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef}, AckDelayExponent: 13, } @@ -68,9 +70,10 @@ var _ = Describe("Transport Parameters", func() { }) It("errors when the stateless_reset_token has the wrong length", func() { - params := &TransportParameters{StatelessResetToken: bytes.Repeat([]byte{100}, 15)} b := &bytes.Buffer{} - params.marshal(b) + utils.BigEndian.WriteUint16(b, uint16(statelessResetTokenParameterID)) + utils.BigEndian.WriteUint16(b, 15) + b.Write(make([]byte, 15)) p := &TransportParameters{} Expect(p.unmarshal(b.Bytes(), protocol.PerspectiveServer)).To(MatchError("wrong length for stateless_reset_token: 15 (expected 16)")) }) @@ -190,9 +193,8 @@ var _ = Describe("Transport Parameters", func() { }) It("errors if the client sent a stateless_reset_token", func() { - params := &TransportParameters{ - StatelessResetToken: make([]byte, 16), - } + var token [16]byte + params := &TransportParameters{StatelessResetToken: &token} b := &bytes.Buffer{} params.marshal(b) p := &TransportParameters{} diff --git a/internal/handshake/transport_parameters.go b/internal/handshake/transport_parameters.go index 69354f33..15cab96b 100644 --- a/internal/handshake/transport_parameters.go +++ b/internal/handshake/transport_parameters.go @@ -46,7 +46,7 @@ type TransportParameters struct { IdleTimeout time.Duration DisableMigration bool - StatelessResetToken []byte + StatelessResetToken *[16]byte OriginalConnectionID protocol.ConnectionID } @@ -94,9 +94,9 @@ func (p *TransportParameters) unmarshal(data []byte, sentBy protocol.Perspective if paramLen != 16 { return fmt.Errorf("wrong length for stateless_reset_token: %d (expected 16)", paramLen) } - b := make([]byte, 16) - r.Read(b) - p.StatelessResetToken = b + var token [16]byte + r.Read(token[:]) + p.StatelessResetToken = &token case originalConnectionIDParameterID: if sentBy == protocol.PerspectiveClient { return errors.New("client sent an original_connection_id") @@ -216,10 +216,10 @@ func (p *TransportParameters) marshal(b *bytes.Buffer) { utils.BigEndian.WriteUint16(b, uint16(disableMigrationParameterID)) utils.BigEndian.WriteUint16(b, 0) } - if len(p.StatelessResetToken) > 0 { + if p.StatelessResetToken != nil { utils.BigEndian.WriteUint16(b, uint16(statelessResetTokenParameterID)) - utils.BigEndian.WriteUint16(b, uint16(len(p.StatelessResetToken))) // should always be 16 bytes - b.Write(p.StatelessResetToken) + utils.BigEndian.WriteUint16(b, 16) + b.Write(p.StatelessResetToken[:]) } // original_connection_id if p.OriginalConnectionID.Len() > 0 { @@ -232,9 +232,9 @@ func (p *TransportParameters) marshal(b *bytes.Buffer) { // String returns a string representation, intended for logging. func (p *TransportParameters) String() string { logString := "&handshake.TransportParameters{OriginalConnectionID: %s, InitialMaxStreamDataBidiLocal: %#x, InitialMaxStreamDataBidiRemote: %#x, InitialMaxStreamDataUni: %#x, InitialMaxData: %#x, MaxBidiStreams: %d, MaxUniStreams: %d, IdleTimeout: %s, AckDelayExponent: %d" - if len(p.StatelessResetToken) > 0 { // the client never sends a stateless reset token + if p.StatelessResetToken != nil { // the client never sends a stateless reset token logString += ", StatelessResetToken: %#x" } logString += "}" - return fmt.Sprintf(logString, p.OriginalConnectionID, p.InitialMaxStreamDataBidiLocal, p.InitialMaxStreamDataBidiRemote, p.InitialMaxStreamDataUni, p.InitialMaxData, p.MaxBidiStreams, p.MaxUniStreams, p.IdleTimeout, p.AckDelayExponent, p.StatelessResetToken) + return fmt.Sprintf(logString, p.OriginalConnectionID, p.InitialMaxStreamDataBidiLocal, p.InitialMaxStreamDataBidiRemote, p.InitialMaxStreamDataUni, p.InitialMaxData, p.MaxBidiStreams, p.MaxUniStreams, p.IdleTimeout, p.AckDelayExponent, *p.StatelessResetToken) } diff --git a/server.go b/server.go index 59c534d7..4f7b418b 100644 --- a/server.go +++ b/server.go @@ -430,6 +430,8 @@ func (s *server) createNewSession( srcConnID protocol.ConnectionID, version protocol.VersionNumber, ) (quicSession, error) { + // TODO(#855): generate a real token + token := [16]byte{42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42} params := &handshake.TransportParameters{ InitialMaxStreamDataBidiLocal: protocol.InitialMaxStreamData, InitialMaxStreamDataBidiRemote: protocol.InitialMaxStreamData, @@ -440,9 +442,8 @@ func (s *server) createNewSession( MaxUniStreams: uint64(s.config.MaxIncomingUniStreams), AckDelayExponent: protocol.AckDelayExponent, DisableMigration: true, - // TODO(#855): generate a real token - StatelessResetToken: bytes.Repeat([]byte{42}, 16), - OriginalConnectionID: origDestConnID, + StatelessResetToken: &token, + OriginalConnectionID: origDestConnID, } sess, err := s.newSession( &conn{pconn: s.conn, currentAddr: remoteAddr}, diff --git a/session.go b/session.go index 70ccc649..bd8ba567 100644 --- a/session.go +++ b/session.go @@ -952,7 +952,7 @@ func (s *session) processTransportParametersForClient(data []byte) (*handshake.T params := &eetp.Parameters // check that the server sent a stateless reset token - if len(params.StatelessResetToken) == 0 { + if params.StatelessResetToken == nil { return nil, errors.New("server didn't send stateless_reset_token") } // check the Retry token diff --git a/session_test.go b/session_test.go index f263cba0..af5e6be2 100644 --- a/session_test.go +++ b/session_test.go @@ -1661,7 +1661,7 @@ var _ = Describe("Client Session", func() { SupportedVersions: []protocol.VersionNumber{sess.version}, Parameters: handshake.TransportParameters{ OriginalConnectionID: protocol.ConnectionID{0xde, 0xca, 0xfb, 0xad}, - StatelessResetToken: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, + StatelessResetToken: &[16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, }, } _, err := sess.processTransportParametersForClient(eetp.Marshal()) @@ -1675,7 +1675,7 @@ var _ = Describe("Client Session", func() { SupportedVersions: []protocol.VersionNumber{sess.version}, Parameters: handshake.TransportParameters{ OriginalConnectionID: protocol.ConnectionID{0xde, 0xca, 0xfb, 0xad}, - StatelessResetToken: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, + StatelessResetToken: &[16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, }, } _, err := sess.processTransportParametersForClient(eetp.Marshal()) @@ -1687,7 +1687,7 @@ var _ = Describe("Client Session", func() { BeforeEach(func() { params = handshake.TransportParameters{ - StatelessResetToken: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, + StatelessResetToken: &[16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, OriginalConnectionID: sess.origDestConnID, } })