Commit 0fb95e78 authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

crypto/tls: remove NPN support

RELNOTE=yes

Fixes #28362

Change-Id: I43813c0c17bbe6c4cbb4d1f121518c434b3f5aa8
Reviewed-on: https://go-review.googlesource.com/c/go/+/174329Reviewed-by: default avatarFilippo Valsorda <filippo@golang.org>
parent 91b55b4f
...@@ -96,6 +96,14 @@ TODO ...@@ -96,6 +96,14 @@ TODO
TODO: <a href="https://golang.org/cl/191999">https://golang.org/cl/191999</a>: remove TLS 1.3 opt-out TODO: <a href="https://golang.org/cl/191999">https://golang.org/cl/191999</a>: remove TLS 1.3 opt-out
</p> </p>
<p><!-- CL 174329 -->
The <code>tls</code> package no longer supports NPN and now only
supports ALPN. In previous releases it supported both. There are
no API changes and code should function identically as before.
Most other clients & servers have already removed NPN support in
favor of the standardized ALPN.
</p>
</dl><!-- crypto/tls --> </dl><!-- crypto/tls -->
<dl id="encoding/asn1"><dt><a href="/pkg/encoding/asn1/">encoding/asn1</a></dt> <dl id="encoding/asn1"><dt><a href="/pkg/encoding/asn1/">encoding/asn1</a></dt>
......
...@@ -1027,8 +1027,6 @@ func (c *Conn) readHandshake() (interface{}, error) { ...@@ -1027,8 +1027,6 @@ func (c *Conn) readHandshake() (interface{}, error) {
m = &certificateVerifyMsg{ m = &certificateVerifyMsg{
hasSignatureAlgorithm: c.vers >= VersionTLS12, hasSignatureAlgorithm: c.vers >= VersionTLS12,
} }
case typeNextProtocol:
m = new(nextProtoMsg)
case typeFinished: case typeFinished:
m = new(finishedMsg) m = new(finishedMsg)
case typeEncryptedExtensions: case typeEncryptedExtensions:
......
...@@ -73,7 +73,6 @@ func (c *Conn) makeClientHello() (*clientHelloMsg, ecdheParameters, error) { ...@@ -73,7 +73,6 @@ func (c *Conn) makeClientHello() (*clientHelloMsg, ecdheParameters, error) {
serverName: hostnameInSNI(config.ServerName), serverName: hostnameInSNI(config.ServerName),
supportedCurves: config.curvePreferences(), supportedCurves: config.curvePreferences(),
supportedPoints: []uint8{pointFormatUncompressed}, supportedPoints: []uint8{pointFormatUncompressed},
nextProtoNeg: len(config.NextProtos) > 0,
secureRenegotiationSupported: true, secureRenegotiationSupported: true,
alpnProtocols: config.NextProtos, alpnProtocols: config.NextProtos,
supportedVersions: supportedVersions, supportedVersions: supportedVersions,
...@@ -673,26 +672,14 @@ func (hs *clientHandshakeState) processServerHello() (bool, error) { ...@@ -673,26 +672,14 @@ func (hs *clientHandshakeState) processServerHello() (bool, error) {
} }
} }
clientDidNPN := hs.hello.nextProtoNeg
clientDidALPN := len(hs.hello.alpnProtocols) > 0 clientDidALPN := len(hs.hello.alpnProtocols) > 0
serverHasNPN := hs.serverHello.nextProtoNeg
serverHasALPN := len(hs.serverHello.alpnProtocol) > 0 serverHasALPN := len(hs.serverHello.alpnProtocol) > 0
if !clientDidNPN && serverHasNPN {
c.sendAlert(alertHandshakeFailure)
return false, errors.New("tls: server advertised unrequested NPN extension")
}
if !clientDidALPN && serverHasALPN { if !clientDidALPN && serverHasALPN {
c.sendAlert(alertHandshakeFailure) c.sendAlert(alertHandshakeFailure)
return false, errors.New("tls: server advertised unrequested ALPN extension") return false, errors.New("tls: server advertised unrequested ALPN extension")
} }
if serverHasNPN && serverHasALPN {
c.sendAlert(alertHandshakeFailure)
return false, errors.New("tls: server advertised both NPN and ALPN extensions")
}
if serverHasALPN { if serverHasALPN {
c.clientProtocol = hs.serverHello.alpnProtocol c.clientProtocol = hs.serverHello.alpnProtocol
c.clientProtocolFallback = false c.clientProtocolFallback = false
...@@ -784,18 +771,6 @@ func (hs *clientHandshakeState) sendFinished(out []byte) error { ...@@ -784,18 +771,6 @@ func (hs *clientHandshakeState) sendFinished(out []byte) error {
if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil { if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil {
return err return err
} }
if hs.serverHello.nextProtoNeg {
nextProto := new(nextProtoMsg)
proto, fallback := mutualProtocol(c.config.NextProtos, hs.serverHello.nextProtos)
nextProto.proto = proto
c.clientProtocol = proto
c.clientProtocolFallback = fallback
hs.finishedHash.Write(nextProto.marshal())
if _, err := c.writeRecord(recordTypeHandshake, nextProto.marshal()); err != nil {
return err
}
}
finished := new(finishedMsg) finished := new(finishedMsg)
finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret) finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret)
......
...@@ -123,9 +123,7 @@ func (hs *clientHandshakeStateTLS13) checkServerHelloOrHRR() error { ...@@ -123,9 +123,7 @@ func (hs *clientHandshakeStateTLS13) checkServerHelloOrHRR() error {
return errors.New("tls: server sent an incorrect legacy version") return errors.New("tls: server sent an incorrect legacy version")
} }
if hs.serverHello.nextProtoNeg || if hs.serverHello.ocspStapling ||
len(hs.serverHello.nextProtos) != 0 ||
hs.serverHello.ocspStapling ||
hs.serverHello.ticketSupported || hs.serverHello.ticketSupported ||
hs.serverHello.secureRenegotiationSupported || hs.serverHello.secureRenegotiationSupported ||
len(hs.serverHello.secureRenegotiation) != 0 || len(hs.serverHello.secureRenegotiation) != 0 ||
......
...@@ -6,8 +6,9 @@ package tls ...@@ -6,8 +6,9 @@ package tls
import ( import (
"fmt" "fmt"
"golang.org/x/crypto/cryptobyte"
"strings" "strings"
"golang.org/x/crypto/cryptobyte"
) )
// The marshalingFunction type is an adapter to allow the use of ordinary // The marshalingFunction type is an adapter to allow the use of ordinary
...@@ -72,7 +73,6 @@ type clientHelloMsg struct { ...@@ -72,7 +73,6 @@ type clientHelloMsg struct {
sessionId []byte sessionId []byte
cipherSuites []uint16 cipherSuites []uint16
compressionMethods []uint8 compressionMethods []uint8
nextProtoNeg bool
serverName string serverName string
ocspStapling bool ocspStapling bool
supportedCurves []CurveID supportedCurves []CurveID
...@@ -121,11 +121,6 @@ func (m *clientHelloMsg) marshal() []byte { ...@@ -121,11 +121,6 @@ func (m *clientHelloMsg) marshal() []byte {
bWithoutExtensions := *b bWithoutExtensions := *b
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
if m.nextProtoNeg {
// draft-agl-tls-nextprotoneg-04
b.AddUint16(extensionNextProtoNeg)
b.AddUint16(0) // empty extension_data
}
if len(m.serverName) > 0 { if len(m.serverName) > 0 {
// RFC 6066, Section 3 // RFC 6066, Section 3
b.AddUint16(extensionServerName) b.AddUint16(extensionServerName)
...@@ -426,9 +421,6 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool { ...@@ -426,9 +421,6 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool {
return false return false
} }
} }
case extensionNextProtoNeg:
// draft-agl-tls-nextprotoneg-04
m.nextProtoNeg = true
case extensionStatusRequest: case extensionStatusRequest:
// RFC 4366, Section 3.6 // RFC 4366, Section 3.6
var statusType uint8 var statusType uint8
...@@ -604,8 +596,6 @@ type serverHelloMsg struct { ...@@ -604,8 +596,6 @@ type serverHelloMsg struct {
sessionId []byte sessionId []byte
cipherSuite uint16 cipherSuite uint16
compressionMethod uint8 compressionMethod uint8
nextProtoNeg bool
nextProtos []string
ocspStapling bool ocspStapling bool
ticketSupported bool ticketSupported bool
secureRenegotiationSupported bool secureRenegotiationSupported bool
...@@ -643,16 +633,6 @@ func (m *serverHelloMsg) marshal() []byte { ...@@ -643,16 +633,6 @@ func (m *serverHelloMsg) marshal() []byte {
bWithoutExtensions := *b bWithoutExtensions := *b
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
if m.nextProtoNeg {
b.AddUint16(extensionNextProtoNeg)
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
for _, proto := range m.nextProtos {
b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddBytes([]byte(proto))
})
}
})
}
if m.ocspStapling { if m.ocspStapling {
b.AddUint16(extensionStatusRequest) b.AddUint16(extensionStatusRequest)
b.AddUint16(0) // empty extension_data b.AddUint16(0) // empty extension_data
...@@ -771,16 +751,6 @@ func (m *serverHelloMsg) unmarshal(data []byte) bool { ...@@ -771,16 +751,6 @@ func (m *serverHelloMsg) unmarshal(data []byte) bool {
} }
switch extension { switch extension {
case extensionNextProtoNeg:
m.nextProtoNeg = true
for !extData.Empty() {
var proto cryptobyte.String
if !extData.ReadUint8LengthPrefixed(&proto) ||
proto.Empty() {
return false
}
m.nextProtos = append(m.nextProtos, string(proto))
}
case extensionStatusRequest: case extensionStatusRequest:
m.ocspStapling = true m.ocspStapling = true
case extensionSessionTicket: case extensionSessionTicket:
...@@ -1579,66 +1549,6 @@ func (m *finishedMsg) unmarshal(data []byte) bool { ...@@ -1579,66 +1549,6 @@ func (m *finishedMsg) unmarshal(data []byte) bool {
s.Empty() s.Empty()
} }
type nextProtoMsg struct {
raw []byte
proto string
}
func (m *nextProtoMsg) marshal() []byte {
if m.raw != nil {
return m.raw
}
l := len(m.proto)
if l > 255 {
l = 255
}
padding := 32 - (l+2)%32
length := l + padding + 2
x := make([]byte, length+4)
x[0] = typeNextProtocol
x[1] = uint8(length >> 16)
x[2] = uint8(length >> 8)
x[3] = uint8(length)
y := x[4:]
y[0] = byte(l)
copy(y[1:], []byte(m.proto[0:l]))
y = y[1+l:]
y[0] = byte(padding)
m.raw = x
return x
}
func (m *nextProtoMsg) unmarshal(data []byte) bool {
m.raw = data
if len(data) < 5 {
return false
}
data = data[4:]
protoLen := int(data[0])
data = data[1:]
if len(data) < protoLen {
return false
}
m.proto = string(data[0:protoLen])
data = data[protoLen:]
if len(data) < 1 {
return false
}
paddingLen := int(data[0])
data = data[1:]
if len(data) != paddingLen {
return false
}
return true
}
type certificateRequestMsg struct { type certificateRequestMsg struct {
raw []byte raw []byte
// hasSignatureAlgorithm indicates whether this message includes a list of // hasSignatureAlgorithm indicates whether this message includes a list of
......
...@@ -26,7 +26,6 @@ var tests = []interface{}{ ...@@ -26,7 +26,6 @@ var tests = []interface{}{
}, },
&certificateStatusMsg{}, &certificateStatusMsg{},
&clientKeyExchangeMsg{}, &clientKeyExchangeMsg{},
&nextProtoMsg{},
&newSessionTicketMsg{}, &newSessionTicketMsg{},
&sessionState{}, &sessionState{},
&sessionStateTLS13{}, &sessionStateTLS13{},
...@@ -127,9 +126,6 @@ func (*clientHelloMsg) Generate(rand *rand.Rand, size int) reflect.Value { ...@@ -127,9 +126,6 @@ func (*clientHelloMsg) Generate(rand *rand.Rand, size int) reflect.Value {
m.cipherSuites[i] = cs m.cipherSuites[i] = cs
} }
m.compressionMethods = randomBytes(rand.Intn(63)+1, rand) m.compressionMethods = randomBytes(rand.Intn(63)+1, rand)
if rand.Intn(10) > 5 {
m.nextProtoNeg = true
}
if rand.Intn(10) > 5 { if rand.Intn(10) > 5 {
m.serverName = randomString(rand.Intn(255), rand) m.serverName = randomString(rand.Intn(255), rand)
for strings.HasSuffix(m.serverName, ".") { for strings.HasSuffix(m.serverName, ".") {
...@@ -206,13 +202,6 @@ func (*serverHelloMsg) Generate(rand *rand.Rand, size int) reflect.Value { ...@@ -206,13 +202,6 @@ func (*serverHelloMsg) Generate(rand *rand.Rand, size int) reflect.Value {
m.cipherSuite = uint16(rand.Int31()) m.cipherSuite = uint16(rand.Int31())
m.compressionMethod = uint8(rand.Intn(256)) m.compressionMethod = uint8(rand.Intn(256))
if rand.Intn(10) > 5 {
m.nextProtoNeg = true
for i := 0; i < rand.Intn(10); i++ {
m.nextProtos = append(m.nextProtos, randomString(20, rand))
}
}
if rand.Intn(10) > 5 { if rand.Intn(10) > 5 {
m.ocspStapling = true m.ocspStapling = true
} }
...@@ -308,12 +297,6 @@ func (*finishedMsg) Generate(rand *rand.Rand, size int) reflect.Value { ...@@ -308,12 +297,6 @@ func (*finishedMsg) Generate(rand *rand.Rand, size int) reflect.Value {
return reflect.ValueOf(m) return reflect.ValueOf(m)
} }
func (*nextProtoMsg) Generate(rand *rand.Rand, size int) reflect.Value {
m := &nextProtoMsg{}
m.proto = randomString(rand.Intn(255), rand)
return reflect.ValueOf(m)
}
func (*newSessionTicketMsg) Generate(rand *rand.Rand, size int) reflect.Value { func (*newSessionTicketMsg) Generate(rand *rand.Rand, size int) reflect.Value {
m := &newSessionTicketMsg{} m := &newSessionTicketMsg{}
m.ticket = randomBytes(rand.Intn(4), rand) m.ticket = randomBytes(rand.Intn(4), rand)
......
...@@ -244,15 +244,6 @@ Curves: ...@@ -244,15 +244,6 @@ Curves:
hs.hello.alpnProtocol = selectedProto hs.hello.alpnProtocol = selectedProto
c.clientProtocol = selectedProto c.clientProtocol = selectedProto
} }
} else {
// Although sending an empty NPN extension is reasonable, Firefox has
// had a bug around this. Best to send nothing at all if
// c.config.NextProtos is empty. See
// https://golang.org/issue/5445.
if hs.clientHello.nextProtoNeg && len(c.config.NextProtos) > 0 {
hs.hello.nextProtoNeg = true
hs.hello.nextProtos = c.config.NextProtos
}
} }
hs.cert, err = c.config.getCertificate(clientHelloInfo(c, hs.clientHello)) hs.cert, err = c.config.getCertificate(clientHelloInfo(c, hs.clientHello))
...@@ -618,20 +609,6 @@ func (hs *serverHandshakeState) readFinished(out []byte) error { ...@@ -618,20 +609,6 @@ func (hs *serverHandshakeState) readFinished(out []byte) error {
return err return err
} }
if hs.hello.nextProtoNeg {
msg, err := c.readHandshake()
if err != nil {
return err
}
nextProto, ok := msg.(*nextProtoMsg)
if !ok {
c.sendAlert(alertUnexpectedMessage)
return unexpectedMessageError(nextProto, msg)
}
hs.finishedHash.Write(nextProto.marshal())
c.clientProtocol = nextProto.proto
}
msg, err := c.readHandshake() msg, err := c.readHandshake()
if err != nil { if err != nil {
return err return err
......
...@@ -510,7 +510,6 @@ func illegalClientHelloChange(ch, ch1 *clientHelloMsg) bool { ...@@ -510,7 +510,6 @@ func illegalClientHelloChange(ch, ch1 *clientHelloMsg) bool {
!bytes.Equal(ch.random, ch1.random) || !bytes.Equal(ch.random, ch1.random) ||
!bytes.Equal(ch.sessionId, ch1.sessionId) || !bytes.Equal(ch.sessionId, ch1.sessionId) ||
!bytes.Equal(ch.compressionMethods, ch1.compressionMethods) || !bytes.Equal(ch.compressionMethods, ch1.compressionMethods) ||
ch.nextProtoNeg != ch1.nextProtoNeg ||
ch.serverName != ch1.serverName || ch.serverName != ch1.serverName ||
ch.ocspStapling != ch1.ocspStapling || ch.ocspStapling != ch1.ocspStapling ||
!bytes.Equal(ch.supportedPoints, ch1.supportedPoints) || !bytes.Equal(ch.supportedPoints, ch1.supportedPoints) ||
......
>>> Flow 1 (client to server) >>> Flow 1 (client to server)
00000000 16 03 01 01 12 01 00 01 0e 03 03 00 00 00 00 00 |................| 00000000 16 03 01 01 0e 01 00 01 0a 03 03 00 00 00 00 00 |................|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020 00 00 00 00 00 00 00 00 00 00 00 20 00 00 00 00 |........... ....| 00000020 00 00 00 00 00 00 00 00 00 00 00 20 00 00 00 00 |........... ....|
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
...@@ -7,22 +7,22 @@ ...@@ -7,22 +7,22 @@
00000050 cc a9 c0 2f c0 2b c0 30 c0 2c c0 27 c0 13 c0 23 |.../.+.0.,.'...#| 00000050 cc a9 c0 2f c0 2b c0 30 c0 2c c0 27 c0 13 c0 23 |.../.+.0.,.'...#|
00000060 c0 09 c0 14 c0 0a 00 9c 00 9d 00 3c 00 2f 00 35 |...........<./.5| 00000060 c0 09 c0 14 c0 0a 00 9c 00 9d 00 3c 00 2f 00 35 |...........<./.5|
00000070 c0 12 00 0a 00 05 c0 11 c0 07 13 01 13 03 13 02 |................| 00000070 c0 12 00 0a 00 05 c0 11 c0 07 13 01 13 03 13 02 |................|
00000080 01 00 00 93 33 74 00 00 00 05 00 05 01 00 00 00 |....3t..........| 00000080 01 00 00 8f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
00000090 00 00 0a 00 0a 00 08 00 1d 00 17 00 18 00 19 00 |................| 00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
000000a0 0b 00 02 01 00 00 0d 00 1a 00 18 08 04 04 03 08 |................| 000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
000000b0 07 08 05 08 06 04 01 05 01 06 01 05 03 06 03 02 |................| 000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
000000c0 01 02 03 ff 01 00 01 00 00 10 00 10 00 0e 06 70 |...............p| 000000c0 01 00 01 00 00 10 00 10 00 0e 06 70 72 6f 74 6f |...........proto|
000000d0 72 6f 74 6f 32 06 70 72 6f 74 6f 31 00 12 00 00 |roto2.proto1....| 000000d0 32 06 70 72 6f 74 6f 31 00 12 00 00 00 2b 00 09 |2.proto1.....+..|
000000e0 00 2b 00 09 08 03 04 03 03 03 02 03 01 00 33 00 |.+............3.| 000000e0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
000000f0 26 00 24 00 1d 00 20 2f e5 7d a3 47 cd 62 43 15 |&.$... /.}.G.bC.| 000000f0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
00000100 28 da ac 5f bb 29 07 30 ff f6 84 af c4 cf c2 ed |(.._.).0........| 00000100 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
00000110 90 99 5f 58 cb 3b 74 |.._X.;t| 00000110 cb 3b 74 |.;t|
>>> Flow 2 (server to client) >>> Flow 2 (server to client)
00000000 16 03 03 00 66 02 00 00 62 03 03 0e b3 00 4c e5 |....f...b.....L.| 00000000 16 03 03 00 66 02 00 00 62 03 03 95 14 55 52 0b |....f...b....UR.|
00000010 e4 08 c5 3d c2 9c 19 a1 de ae 43 24 9a 4d 81 99 |...=......C$.M..| 00000010 e7 c1 15 6b dc 19 3b 17 9e bb 6a b7 61 82 dc 59 |...k..;...j.a..Y|
00000020 df 60 cf a5 be ae c1 e8 e8 b9 a8 20 14 e6 e1 91 |.`......... ....| 00000020 d3 a4 7c e1 c3 83 cc e2 e5 56 e0 20 3c 82 0d 54 |..|......V. <..T|
00000030 7a ab 9f 7b 3c dc c5 71 4b 28 80 5e fa 56 c9 b7 |z..{<..qK(.^.V..| 00000030 2b 78 fe 50 cb 4e c1 69 d7 6f b3 9f ac 2e 27 c8 |+x.P.N.i.o....'.|
00000040 d4 2f 0e 80 49 df 81 93 df 5d 34 49 cc a8 00 00 |./..I....]4I....| 00000040 c6 7a 70 27 1e 14 67 43 4c f1 7d d7 cc a8 00 00 |.zp'..gCL.}.....|
00000050 1a ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 10 |................| 00000050 1a ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 10 |................|
00000060 00 09 00 07 06 70 72 6f 74 6f 31 16 03 03 02 59 |.....proto1....Y| 00000060 00 09 00 07 06 70 72 6f 74 6f 31 16 03 03 02 59 |.....proto1....Y|
00000070 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 |...U..R..O0..K0.| 00000070 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 |...U..R..O0..K0.|
...@@ -63,31 +63,31 @@ ...@@ -63,31 +63,31 @@
000002a0 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 |.....@.a.Lr+...F| 000002a0 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 |.....@.a.Lr+...F|
000002b0 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 |..M...>...B...=.| 000002b0 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 |..M...>...B...=.|
000002c0 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 ac 0c 00 |`.\!.;..........| 000002c0 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 ac 0c 00 |`.\!.;..........|
000002d0 00 a8 03 00 1d 20 18 37 3a d3 0a 4f 9b 95 c7 f0 |..... .7:..O....| 000002d0 00 a8 03 00 1d 20 c3 e3 43 9c 5d 0f 09 61 ae 18 |..... ..C.]..a..|
000002e0 a2 00 43 5f df 2e a8 16 a9 9f 2a 0e 51 cf c9 b9 |..C_......*.Q...| 000002e0 66 05 b1 7d c1 9f e5 26 9c a7 97 d6 1f 9a 7c ff |f..}...&......|.|
000002f0 14 62 a7 ab 4b 6a 08 04 00 80 1a b2 78 e7 cd b6 |.b..Kj......x...| 000002f0 8c 34 a1 32 a2 35 08 04 00 80 6c 50 a1 80 d9 20 |.4.2.5....lP... |
00000300 18 65 31 19 f9 91 9f a6 cb 77 97 69 86 27 ef 06 |.e1......w.i.'..| 00000300 56 08 da d9 5b 77 4d ad 43 66 71 15 ec fe db 02 |V...[wM.Cfq.....|
00000310 b5 bc f4 8f 75 96 01 72 64 2c d4 e4 67 0a d5 58 |....u..rd,..g..X| 00000310 fb 40 d8 8d 67 22 e2 1b ec 8d b9 4e ba 65 01 8b |.@..g".....N.e..|
00000320 e0 e1 05 82 a6 58 f6 e0 06 c2 15 03 69 ba 5a a0 |.....X......i.Z.| 00000320 70 e0 83 bc 06 1b 14 8f 07 cf a6 08 58 c3 77 94 |p...........X.w.|
00000330 2b af 6f b1 cd 16 84 1d 89 9c d0 c7 d2 c7 83 e8 |+.o.............| 00000330 0f 94 53 62 54 6c 1f 92 22 9d ae f8 5a ad d5 f3 |..SbTl.."...Z...|
00000340 43 b7 4f e8 ca 97 c0 e2 57 d0 10 48 0c 26 cf 58 |C.O.....W..H.&.X| 00000340 8a f7 e6 93 8c 0e 48 1b 23 89 d8 bd e9 5c 50 cd |......H.#....\P.|
00000350 50 69 d8 86 b6 f5 aa 02 b8 f6 41 c4 15 52 99 52 |Pi........A..R.R| 00000350 07 3d 7e 8e b0 d6 65 44 58 62 03 a1 d9 94 72 f0 |.=~...eDXb....r.|
00000360 05 05 5b 42 80 6d 8a bf 7a e6 f3 60 c5 67 23 dc |..[B.m..z..`.g#.| 00000360 25 a9 e0 c1 be ac 32 05 59 f7 7f 6e 13 23 70 5a |%.....2.Y..n.#pZ|
00000370 39 4b e6 74 0e 0e 47 a7 57 02 16 03 03 00 04 0e |9K.t..G.W.......| 00000370 65 ba a2 d7 da 3c a2 9e 6b 13 16 03 03 00 04 0e |e....<..k.......|
00000380 00 00 00 |...| 00000380 00 00 00 |...|
>>> Flow 3 (client to server) >>> Flow 3 (client to server)
00000000 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.| 00000000 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.|
00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....| 00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....|
00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 03 00 01 01 |....._X.;t......| 00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 03 00 01 01 |....._X.;t......|
00000030 16 03 03 00 20 0d 3c cf 6f 13 e3 73 d2 c5 05 06 |.... .<.o..s....| 00000030 16 03 03 00 20 5e 91 45 7d ab 7c b7 6f 57 a6 d0 |.... ^.E}.|.oW..|
00000040 85 8d 41 e0 46 3b 25 e7 0a ae b9 00 1e c3 3f 61 |..A.F;%.......?a| 00000040 17 83 cb 40 1b 76 6b 5e 80 39 03 2f 6d 2f 10 8e |...@.vk^.9./m/..|
00000050 82 2d e1 19 a4 |.-...| 00000050 74 33 12 54 8d |t3.T.|
>>> Flow 4 (server to client) >>> Flow 4 (server to client)
00000000 14 03 03 00 01 01 16 03 03 00 20 43 1a 5d c1 dc |.......... C.]..| 00000000 14 03 03 00 01 01 16 03 03 00 20 f1 3c 7a 28 eb |.......... .<z(.|
00000010 42 10 81 bc af 2d 40 82 fa 27 41 81 cc e5 97 99 |B....-@..'A.....| 00000010 0a b1 bf 42 28 de 07 83 76 c6 2c 94 b7 d5 ef f3 |...B(...v.,.....|
00000020 80 27 3a b5 db f5 8e 2a 6d 72 86 |.':....*mr.| 00000020 0b 9c 0c 2e d3 ab 8a a9 03 d2 c0 |...........|
>>> Flow 5 (client to server) >>> Flow 5 (client to server)
00000000 17 03 03 00 16 f1 0a 98 3b 2a 06 98 ad 46 f5 f7 |........;*...F..| 00000000 17 03 03 00 16 dc f6 18 54 22 e0 9c 08 bf db a8 |........T"......|
00000010 42 cf 89 c0 d4 a7 08 df bb dc 4d 15 03 03 00 12 |B.........M.....| 00000010 62 2a 64 9e 06 43 0f 22 18 0e 34 15 03 03 00 12 |b*d..C."..4.....|
00000020 9c d4 d2 a1 fb 38 98 31 7d ce 39 50 0b 58 d8 a8 |.....8.1}.9P.X..| 00000020 20 2f f4 76 cd dc 82 eb 30 f9 e0 42 6b 29 16 ed | /.v....0..Bk)..|
00000030 3e 19 |>.| 00000030 7c f0 ||.|
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment