mirror of
https://github.com/refraction-networking/utls.git
synced 2025-04-02 03:27:35 +03:00
crypto/tls: clarify group selection logic
I initially thought the logic was broken, but writing the test I realized it was actually very clever (derogative). It was relying on the outer loop continuing after a supported match without a key share, allowing a later key share to override it (but not a later supported match because of the "if selectedGroup != 0 { continue }"). Replaced the clever loop with two hopefully more understandable loops, and added a test (which was already passing). We were however not checking that the selected group is in the supported list if we found it in key shares first. (This was only a MAY.) Fixed. Fixes #65686 Change-Id: I09ea44f90167ffa36809deb78255ed039a217b6d Reviewed-on: https://go-review.googlesource.com/c/go/+/586655 Reviewed-by: Roland Shoemaker <roland@golang.org> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Filippo Valsorda <filippo@golang.org>
This commit is contained in:
parent
2a85364a09
commit
245de0a13b
9 changed files with 248 additions and 60 deletions
|
@ -26,33 +26,42 @@ import (
|
|||
)
|
||||
|
||||
func TestBoringServerProtocolVersion(t *testing.T) {
|
||||
test := func(name string, v uint16, msg string) {
|
||||
test := func(t *testing.T, name string, v uint16, msg string) {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
serverConfig := testConfig.Clone()
|
||||
serverConfig.MinVersion = VersionSSL30
|
||||
clientHello := &clientHelloMsg{
|
||||
vers: v,
|
||||
random: make([]byte, 32),
|
||||
cipherSuites: allCipherSuites(),
|
||||
compressionMethods: []uint8{compressionNone},
|
||||
supportedVersions: []uint16{v},
|
||||
clientConfig := testConfig.Clone()
|
||||
clientConfig.MinVersion = v
|
||||
clientConfig.MaxVersion = v
|
||||
_, _, err := testHandshake(t, clientConfig, serverConfig)
|
||||
if msg == "" {
|
||||
if err != nil {
|
||||
t.Fatalf("got error: %v, expected success", err)
|
||||
}
|
||||
} else {
|
||||
if err == nil {
|
||||
t.Fatalf("got success, expected error")
|
||||
}
|
||||
if !strings.Contains(err.Error(), msg) {
|
||||
t.Fatalf("got error %v, expected %q", err, msg)
|
||||
}
|
||||
}
|
||||
testClientHelloFailure(t, serverConfig, clientHello, msg)
|
||||
})
|
||||
}
|
||||
|
||||
test("VersionTLS10", VersionTLS10, "")
|
||||
test("VersionTLS11", VersionTLS11, "")
|
||||
test("VersionTLS12", VersionTLS12, "")
|
||||
test("VersionTLS13", VersionTLS13, "")
|
||||
test(t, "VersionTLS10", VersionTLS10, "")
|
||||
test(t, "VersionTLS11", VersionTLS11, "")
|
||||
test(t, "VersionTLS12", VersionTLS12, "")
|
||||
test(t, "VersionTLS13", VersionTLS13, "")
|
||||
|
||||
fipstls.Force()
|
||||
defer fipstls.Abandon()
|
||||
test("VersionSSL30", VersionSSL30, "client offered only unsupported versions")
|
||||
test("VersionTLS10", VersionTLS10, "client offered only unsupported versions")
|
||||
test("VersionTLS11", VersionTLS11, "client offered only unsupported versions")
|
||||
test("VersionTLS12", VersionTLS12, "")
|
||||
test("VersionTLS13", VersionTLS13, "client offered only unsupported versions")
|
||||
t.Run("fipstls", func(t *testing.T) {
|
||||
fipstls.Force()
|
||||
defer fipstls.Abandon()
|
||||
test(t, "VersionTLS10", VersionTLS10, "supported versions")
|
||||
test(t, "VersionTLS11", VersionTLS11, "supported versions")
|
||||
test(t, "VersionTLS12", VersionTLS12, "")
|
||||
test(t, "VersionTLS13", VersionTLS13, "supported versions")
|
||||
})
|
||||
}
|
||||
|
||||
func isBoringVersion(v uint16) bool {
|
||||
|
@ -154,26 +163,22 @@ func TestBoringServerCurves(t *testing.T) {
|
|||
|
||||
for _, curveid := range defaultCurvePreferences {
|
||||
t.Run(fmt.Sprintf("curve=%d", curveid), func(t *testing.T) {
|
||||
clientHello := &clientHelloMsg{
|
||||
vers: VersionTLS12,
|
||||
random: make([]byte, 32),
|
||||
cipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
|
||||
compressionMethods: []uint8{compressionNone},
|
||||
supportedCurves: []CurveID{curveid},
|
||||
supportedPoints: []uint8{pointFormatUncompressed},
|
||||
clientConfig := testConfig.Clone()
|
||||
clientConfig.CurvePreferences = []CurveID{curveid}
|
||||
if _, _, err := testHandshake(t, clientConfig, serverConfig); err != nil {
|
||||
t.Fatalf("got error: %v, expected success", err)
|
||||
}
|
||||
|
||||
testClientHello(t, serverConfig, clientHello)
|
||||
|
||||
// With fipstls forced, bad curves should be rejected.
|
||||
t.Run("fipstls", func(t *testing.T) {
|
||||
fipstls.Force()
|
||||
defer fipstls.Abandon()
|
||||
msg := ""
|
||||
if !isBoringCurve(curveid) {
|
||||
msg = "no cipher suite supported by both client and server"
|
||||
_, _, err := testHandshake(t, clientConfig, serverConfig)
|
||||
if err != nil && isBoringCurve(curveid) {
|
||||
t.Fatalf("got error: %v, expected success", err)
|
||||
} else if err == nil && !isBoringCurve(curveid) {
|
||||
t.Fatalf("got success, expected error")
|
||||
}
|
||||
testClientHelloFailure(t, serverConfig, clientHello, msg)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -299,6 +299,9 @@ type ConnectionState struct {
|
|||
|
||||
// ekm is a closure exposed via ExportKeyingMaterial.
|
||||
ekm func(label string, context []byte, length int) ([]byte, error)
|
||||
|
||||
// testingOnlyDidHRR is true if a HelloRetryRequest was sent/received.
|
||||
testingOnlyDidHRR bool
|
||||
}
|
||||
|
||||
// ExportKeyingMaterial returns length bytes of exported key material in a new
|
||||
|
|
2
conn.go
2
conn.go
|
@ -48,6 +48,7 @@ type Conn struct {
|
|||
handshakes int
|
||||
extMasterSecret bool
|
||||
didResume bool // whether this connection was a session resumption
|
||||
didHRR bool // whether a HelloRetryRequest was sent/received
|
||||
cipherSuite uint16
|
||||
ocspResponse []byte // stapled OCSP response
|
||||
scts [][]byte // signed certificate timestamps from server
|
||||
|
@ -1608,6 +1609,7 @@ func (c *Conn) connectionStateLocked() ConnectionState {
|
|||
state.Version = c.vers
|
||||
state.NegotiatedProtocol = c.clientProtocol
|
||||
state.DidResume = c.didResume
|
||||
state.testingOnlyDidHRR = c.didHRR
|
||||
state.NegotiatedProtocolIsMutual = true
|
||||
state.ServerName = c.serverName
|
||||
state.CipherSuite = c.cipherSuite
|
||||
|
|
|
@ -659,6 +659,12 @@ func TestHandshakeClientHelloRetryRequest(t *testing.T) {
|
|||
name: "HelloRetryRequest",
|
||||
args: []string{"-cipher", "ECDHE-RSA-AES128-GCM-SHA256", "-curves", "P-256"},
|
||||
config: config,
|
||||
validate: func(cs ConnectionState) error {
|
||||
if !cs.testingOnlyDidHRR {
|
||||
return errors.New("expected HelloRetryRequest")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
runClientTestTLS13(t, test)
|
||||
|
|
|
@ -307,6 +307,7 @@ func (hs *clientHandshakeStateTLS13) processHelloRetryRequest() error {
|
|||
return err
|
||||
}
|
||||
|
||||
c.didHRR = true
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -52,16 +52,33 @@ func testClientHelloFailure(t *testing.T, serverConfig *Config, m handshakeMessa
|
|||
ctx := context.Background()
|
||||
conn := Server(s, serverConfig)
|
||||
ch, err := conn.readClientHello(ctx)
|
||||
hs := serverHandshakeState{
|
||||
c: conn,
|
||||
ctx: ctx,
|
||||
clientHello: ch,
|
||||
}
|
||||
if err == nil {
|
||||
err = hs.processClientHello()
|
||||
}
|
||||
if err == nil {
|
||||
err = hs.pickCipherSuite()
|
||||
if conn.vers == VersionTLS13 {
|
||||
hs := serverHandshakeStateTLS13{
|
||||
c: conn,
|
||||
ctx: ctx,
|
||||
clientHello: ch,
|
||||
}
|
||||
if err == nil {
|
||||
err = hs.processClientHello()
|
||||
}
|
||||
if err == nil {
|
||||
err = hs.checkForResumption()
|
||||
}
|
||||
if err == nil {
|
||||
err = hs.pickCertificate()
|
||||
}
|
||||
} else {
|
||||
hs := serverHandshakeState{
|
||||
c: conn,
|
||||
ctx: ctx,
|
||||
clientHello: ch,
|
||||
}
|
||||
if err == nil {
|
||||
err = hs.processClientHello()
|
||||
}
|
||||
if err == nil {
|
||||
err = hs.pickCipherSuite()
|
||||
}
|
||||
}
|
||||
s.Close()
|
||||
if len(expectedSubStr) == 0 {
|
||||
|
@ -903,10 +920,52 @@ func TestHandshakeServerHelloRetryRequest(t *testing.T) {
|
|||
name: "HelloRetryRequest",
|
||||
command: []string{"openssl", "s_client", "-no_ticket", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256", "-curves", "X25519:P-256"},
|
||||
config: config,
|
||||
validate: func(cs ConnectionState) error {
|
||||
if !cs.testingOnlyDidHRR {
|
||||
return errors.New("expected HelloRetryRequest")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
runServerTestTLS13(t, test)
|
||||
}
|
||||
|
||||
// TestHandshakeServerKeySharePreference checks that we prefer a key share even
|
||||
// if it's later in the CurvePreferences order.
|
||||
func TestHandshakeServerKeySharePreference(t *testing.T) {
|
||||
config := testConfig.Clone()
|
||||
config.CurvePreferences = []CurveID{X25519, CurveP256}
|
||||
|
||||
test := &serverTest{
|
||||
name: "KeySharePreference",
|
||||
command: []string{"openssl", "s_client", "-no_ticket", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256", "-curves", "P-256:X25519"},
|
||||
config: config,
|
||||
validate: func(cs ConnectionState) error {
|
||||
if cs.testingOnlyDidHRR {
|
||||
return errors.New("unexpected HelloRetryRequest")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
runServerTestTLS13(t, test)
|
||||
}
|
||||
|
||||
// TestHandshakeServerUnsupportedKeyShare tests a client that sends a key share
|
||||
// that's not in the supported groups list.
|
||||
func TestHandshakeServerUnsupportedKeyShare(t *testing.T) {
|
||||
pk, _ := ecdh.X25519().GenerateKey(rand.Reader)
|
||||
clientHello := &clientHelloMsg{
|
||||
vers: VersionTLS12,
|
||||
random: make([]byte, 32),
|
||||
supportedVersions: []uint16{VersionTLS13},
|
||||
cipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256},
|
||||
compressionMethods: []uint8{compressionNone},
|
||||
keyShares: []keyShare{{group: X25519, data: pk.PublicKey().Bytes()}},
|
||||
supportedCurves: []CurveID{CurveP256},
|
||||
}
|
||||
testClientHelloFailure(t, testConfig, clientHello, "client sent key share for group it does not support")
|
||||
}
|
||||
|
||||
func TestHandshakeServerALPN(t *testing.T) {
|
||||
config := testConfig.Clone()
|
||||
config.NextProtos = []string{"proto1", "proto2"}
|
||||
|
@ -1932,6 +1991,7 @@ func TestAESCipherReorderingTLS13(t *testing.T) {
|
|||
supportedVersions: []uint16{VersionTLS13},
|
||||
compressionMethods: []uint8{compressionNone},
|
||||
keyShares: []keyShare{{group: X25519, data: pk.PublicKey().Bytes()}},
|
||||
supportedCurves: []CurveID{X25519},
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"hash"
|
||||
"internal/byteorder"
|
||||
"io"
|
||||
"slices"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -181,21 +182,25 @@ func (hs *serverHandshakeStateTLS13) processClientHello() error {
|
|||
// groups with a key share, to avoid a HelloRetryRequest round-trip.
|
||||
var selectedGroup CurveID
|
||||
var clientKeyShare *keyShare
|
||||
GroupSelection:
|
||||
for _, preferredGroup := range c.config.curvePreferences() {
|
||||
for _, ks := range hs.clientHello.keyShares {
|
||||
if ks.group == preferredGroup {
|
||||
selectedGroup = ks.group
|
||||
clientKeyShare = &ks
|
||||
break GroupSelection
|
||||
preferredGroups := c.config.curvePreferences()
|
||||
for _, preferredGroup := range preferredGroups {
|
||||
ki := slices.IndexFunc(hs.clientHello.keyShares, func(ks keyShare) bool {
|
||||
return ks.group == preferredGroup
|
||||
})
|
||||
if ki != -1 {
|
||||
clientKeyShare = &hs.clientHello.keyShares[ki]
|
||||
selectedGroup = clientKeyShare.group
|
||||
if !slices.Contains(hs.clientHello.supportedCurves, selectedGroup) {
|
||||
c.sendAlert(alertIllegalParameter)
|
||||
return errors.New("tls: client sent key share for group it does not support")
|
||||
}
|
||||
break
|
||||
}
|
||||
if selectedGroup != 0 {
|
||||
continue
|
||||
}
|
||||
for _, group := range hs.clientHello.supportedCurves {
|
||||
if group == preferredGroup {
|
||||
selectedGroup = group
|
||||
}
|
||||
if selectedGroup == 0 {
|
||||
for _, preferredGroup := range preferredGroups {
|
||||
if slices.Contains(hs.clientHello.supportedCurves, preferredGroup) {
|
||||
selectedGroup = preferredGroup
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -532,6 +537,7 @@ func (hs *serverHandshakeStateTLS13) doHelloRetryRequest(selectedGroup CurveID)
|
|||
return errors.New("tls: client illegally modified second ClientHello")
|
||||
}
|
||||
|
||||
c.didHRR = true
|
||||
hs.clientHello = clientHello
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -296,6 +296,8 @@ Dialing:
|
|||
|
||||
case c2 := <-localListener.ch:
|
||||
if c2.RemoteAddr().String() == c1.LocalAddr().String() {
|
||||
t.Cleanup(func() { c1.Close() })
|
||||
t.Cleanup(func() { c2.Close() })
|
||||
return c1, c2
|
||||
}
|
||||
t.Logf("localPipe: unexpected connection: %v != %v", c2.RemoteAddr(), c1.LocalAddr())
|
||||
|
@ -399,7 +401,7 @@ func runMain(m *testing.M) int {
|
|||
func testHandshake(t *testing.T, clientConfig, serverConfig *Config) (serverState, clientState ConnectionState, err error) {
|
||||
const sentinel = "SENTINEL\n"
|
||||
c, s := localPipe(t)
|
||||
errChan := make(chan error)
|
||||
errChan := make(chan error, 1)
|
||||
go func() {
|
||||
cli := Client(c, clientConfig)
|
||||
err := cli.Handshake()
|
||||
|
@ -408,7 +410,7 @@ func testHandshake(t *testing.T, clientConfig, serverConfig *Config) (serverStat
|
|||
c.Close()
|
||||
return
|
||||
}
|
||||
defer cli.Close()
|
||||
defer func() { errChan <- nil }()
|
||||
clientState = cli.ConnectionState()
|
||||
buf, err := io.ReadAll(cli)
|
||||
if err != nil {
|
||||
|
@ -417,7 +419,9 @@ func testHandshake(t *testing.T, clientConfig, serverConfig *Config) (serverStat
|
|||
if got := string(buf); got != sentinel {
|
||||
t.Errorf("read %q from TLS connection, but expected %q", got, sentinel)
|
||||
}
|
||||
errChan <- nil
|
||||
if err := cli.Close(); err != nil {
|
||||
t.Errorf("failed to call cli.Close: %v", err)
|
||||
}
|
||||
}()
|
||||
server := Server(s, serverConfig)
|
||||
err = server.Handshake()
|
||||
|
@ -429,11 +433,11 @@ func testHandshake(t *testing.T, clientConfig, serverConfig *Config) (serverStat
|
|||
if err := server.Close(); err != nil {
|
||||
t.Errorf("failed to call server.Close: %v", err)
|
||||
}
|
||||
err = <-errChan
|
||||
} else {
|
||||
err = fmt.Errorf("server: %v", err)
|
||||
s.Close()
|
||||
<-errChan
|
||||
}
|
||||
err = errors.Join(err, <-errChan)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
101
testdata/Server-TLSv13-KeySharePreference
vendored
Normal file
101
testdata/Server-TLSv13-KeySharePreference
vendored
Normal file
|
@ -0,0 +1,101 @@
|
|||
>>> Flow 1 (client to server)
|
||||
00000000 16 03 01 00 e5 01 00 00 e1 03 03 58 2d 84 f2 4f |...........X-..O|
|
||||
00000010 6d 10 9d f6 5a 67 c7 92 78 e6 7d 96 96 fe db 37 |m...Zg..x.}....7|
|
||||
00000020 07 44 e3 2e 85 3f 1a 5f f1 2a 24 20 cb e8 e8 c4 |.D...?._.*$ ....|
|
||||
00000030 e9 28 01 21 9f 82 d2 da 6b 3e a0 7f 0d 20 95 12 |.(.!....k>... ..|
|
||||
00000040 39 5b 3f f8 04 86 df 9b 72 3b 74 e2 00 04 13 03 |9[?.....r;t.....|
|
||||
00000050 00 ff 01 00 00 94 00 0b 00 04 03 00 01 02 00 0a |................|
|
||||
00000060 00 06 00 04 00 17 00 1d 00 16 00 00 00 17 00 00 |................|
|
||||
00000070 00 0d 00 1e 00 1c 04 03 05 03 06 03 08 07 08 08 |................|
|
||||
00000080 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 |................|
|
||||
00000090 06 01 00 2b 00 03 02 03 04 00 2d 00 02 01 01 00 |...+......-.....|
|
||||
000000a0 33 00 47 00 45 00 17 00 41 04 63 03 f6 90 df 1f |3.G.E...A.c.....|
|
||||
000000b0 d0 03 96 24 21 3d e4 c0 5d 38 5f 53 85 a4 9c d8 |...$!=..]8_S....|
|
||||
000000c0 f7 b0 9c 64 5f 53 c3 66 9b f5 e0 5a 60 0b b2 e8 |...d_S.f...Z`...|
|
||||
000000d0 2b d0 6a a2 ff 1d 07 8b 5f a8 37 e4 74 35 15 b1 |+.j....._.7.t5..|
|
||||
000000e0 06 de 79 3b f4 69 52 2a ad 66 |..y;.iR*.f|
|
||||
>>> Flow 2 (server to client)
|
||||
00000000 16 03 03 00 9b 02 00 00 97 03 03 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 cb e8 e8 c4 |........... ....|
|
||||
00000030 e9 28 01 21 9f 82 d2 da 6b 3e a0 7f 0d 20 95 12 |.(.!....k>... ..|
|
||||
00000040 39 5b 3f f8 04 86 df 9b 72 3b 74 e2 13 03 00 00 |9[?.....r;t.....|
|
||||
00000050 4f 00 2b 00 02 03 04 00 33 00 45 00 17 00 41 04 |O.+.....3.E...A.|
|
||||
00000060 1e 18 37 ef 0d 19 51 88 35 75 71 b5 e5 54 5b 12 |..7...Q.5uq..T[.|
|
||||
00000070 2e 8f 09 67 fd a7 24 20 3e b2 56 1c ce 97 28 5e |...g..$ >.V...(^|
|
||||
00000080 f8 2b 2d 4f 9e f1 07 9f 6c 4b 5b 83 56 e2 32 42 |.+-O....lK[.V.2B|
|
||||
00000090 e9 58 b6 d7 49 a6 b5 68 1a 41 03 56 6b dc 5a 89 |.X..I..h.A.Vk.Z.|
|
||||
000000a0 14 03 03 00 01 01 17 03 03 00 17 f8 6a 35 d1 d7 |............j5..|
|
||||
000000b0 a0 09 48 20 66 ea 1d 4e a4 05 2b d6 24 ea 0d cb |..H f..N..+.$...|
|
||||
000000c0 68 8b 17 03 03 02 6d 16 c5 3b c2 80 85 49 51 1f |h.....m..;...IQ.|
|
||||
000000d0 4e 0e 8a 11 63 95 9b 83 46 a9 19 43 90 ee 55 ae |N...c...F..C..U.|
|
||||
000000e0 4f 09 ae cf fd 64 dd a9 c0 af 31 fd 95 29 20 9f |O....d....1..) .|
|
||||
000000f0 da d4 27 97 2c da da 2c c8 e7 e5 c2 6b 24 5f dd |..'.,..,....k$_.|
|
||||
00000100 68 86 b1 9b 01 95 8a 78 bb 10 26 66 24 d4 59 df |h......x..&f$.Y.|
|
||||
00000110 6d b4 56 c4 23 56 5d 3c fc 6d 69 ce eb e2 9c 30 |m.V.#V]<.mi....0|
|
||||
00000120 da 34 39 32 80 a7 26 d6 e2 11 33 a5 c1 5d 75 07 |.492..&...3..]u.|
|
||||
00000130 f5 f6 98 9e f2 26 49 96 52 fb 56 6d 34 67 45 15 |.....&I.R.Vm4gE.|
|
||||
00000140 97 0d 0d 5e 7e 63 6b 42 0e 6f 2c 3b 11 06 d5 a4 |...^~ckB.o,;....|
|
||||
00000150 00 92 2d 39 62 ea f4 28 04 ee e4 f4 78 f4 d2 72 |..-9b..(....x..r|
|
||||
00000160 f7 65 61 43 76 12 59 90 a3 15 71 07 78 dc 61 cf |.eaCv.Y...q.x.a.|
|
||||
00000170 62 6e 7d 2d 7e b0 0f e3 ca 21 1b 13 96 ef 96 23 |bn}-~....!.....#|
|
||||
00000180 86 31 2a 53 b0 13 a3 23 29 74 2c 98 3b 75 a2 96 |.1*S...#)t,.;u..|
|
||||
00000190 7b 4a cb 22 f3 63 84 17 9b 25 a8 10 75 88 3c fd |{J.".c...%..u.<.|
|
||||
000001a0 d5 49 c3 97 c3 78 83 c1 24 f3 7f 21 63 e8 b2 01 |.I...x..$..!c...|
|
||||
000001b0 b0 92 b8 8b f2 83 64 2f a8 8f b9 18 14 44 54 6a |......d/.....DTj|
|
||||
000001c0 a9 d6 68 5c be 50 69 8d 35 16 5e 8d 9a 6a f0 5b |..h\.Pi.5.^..j.[|
|
||||
000001d0 a4 f1 5b 51 3e 5b d4 d1 41 06 3c c7 09 27 96 a8 |..[Q>[..A.<..'..|
|
||||
000001e0 81 07 d2 33 27 3c a6 a9 bb 7b 80 28 58 e4 b0 dd |...3'<...{.(X...|
|
||||
000001f0 a8 9e b2 61 ed 5b 57 c8 b2 a2 7f 6b f7 0f ee 3d |...a.[W....k...=|
|
||||
00000200 9c 6d a1 76 55 3e af aa 17 c8 a8 ec c6 14 31 77 |.m.vU>........1w|
|
||||
00000210 38 a3 9c 15 3f 0e cc 63 43 8f b0 c1 14 97 ee 85 |8...?..cC.......|
|
||||
00000220 30 08 b1 95 0c 7f 5b 95 4d 4f 18 26 d8 45 cb b4 |0.....[.MO.&.E..|
|
||||
00000230 b7 1b f5 a5 d5 e5 21 da 53 88 57 09 ed 30 fe d1 |......!.S.W..0..|
|
||||
00000240 ac ee c7 80 ee a9 96 31 92 4c a1 e2 2c a8 f5 b1 |.......1.L..,...|
|
||||
00000250 d9 3c bd c8 e6 1b ba 7c 91 d6 6c d4 ae 0a 15 50 |.<.....|..l....P|
|
||||
00000260 b9 24 80 14 ff 28 98 94 a7 7f d4 13 16 1f 03 bf |.$...(..........|
|
||||
00000270 72 83 94 a3 8a 6d b6 d7 b2 c7 22 56 38 f2 15 e1 |r....m...."V8...|
|
||||
00000280 ea 1f 78 d0 ff ac c4 19 54 a1 c6 2d 8a da cd f3 |..x.....T..-....|
|
||||
00000290 6e 45 b3 a4 dc e3 a0 6e f8 18 af a6 c6 20 ce a7 |nE.....n..... ..|
|
||||
000002a0 eb dc 42 06 bd d4 bf a0 ef 36 4c f6 38 42 3d f7 |..B......6L.8B=.|
|
||||
000002b0 a3 a5 ac 4d b3 71 36 9b 00 ee 1f 40 fa bc b3 d4 |...M.q6....@....|
|
||||
000002c0 5b 49 79 4f 16 fd 3e 4f ab 8e cc 92 7d f3 1d c7 |[IyO..>O....}...|
|
||||
000002d0 13 76 49 56 1c 59 13 56 3b 6b 33 ed 1a 85 9c b7 |.vIV.Y.V;k3.....|
|
||||
000002e0 a1 55 84 83 a1 df d6 53 0c c1 b6 63 63 b2 58 84 |.U.....S...cc.X.|
|
||||
000002f0 12 f6 99 7a ac c5 ee 53 69 9e 86 76 88 aa 7b 2f |...z...Si..v..{/|
|
||||
00000300 f8 48 0b 05 e1 2a 1c 0d 56 ae 79 9e 68 4f b5 85 |.H...*..V.y.hO..|
|
||||
00000310 df cc 11 05 33 94 55 e6 16 d4 d5 78 b4 d1 c3 2c |....3.U....x...,|
|
||||
00000320 2d 3c ac 45 6e fd 1e e0 79 5c 23 c3 57 66 3e d2 |-<.En...y\#.Wf>.|
|
||||
00000330 22 39 21 df 17 03 03 00 99 a9 e3 ac d5 82 cc bd |"9!.............|
|
||||
00000340 74 c3 92 13 4d 32 fc ff e4 63 ec ea 81 40 47 bb |t...M2...c...@G.|
|
||||
00000350 3f ad 65 d4 fe 4f 0c c0 6a b0 78 c4 4f 0d e8 73 |?.e..O..j.x.O..s|
|
||||
00000360 7c ee 9b ff 61 f8 4b 17 32 92 5d e5 49 ea 7b 38 ||...a.K.2.].I.{8|
|
||||
00000370 6b db a2 4b 64 1d 7f 42 ce 4d f0 d8 dc 9c 93 f4 |k..Kd..B.M......|
|
||||
00000380 23 5d d5 dd 34 90 51 42 3d 0e bf 69 31 d8 0f e6 |#]..4.QB=..i1...|
|
||||
00000390 14 5a ec 52 1e d5 41 a6 25 7c 9b 40 f5 92 58 17 |.Z.R..A.%|.@..X.|
|
||||
000003a0 80 68 a2 43 58 d3 d9 7c 7a 1f 90 4f a5 08 f8 0f |.h.CX..|z..O....|
|
||||
000003b0 31 7b bd cc 74 3d f8 73 7d 0a 6c 12 25 53 b3 99 |1{..t=.s}.l.%S..|
|
||||
000003c0 c7 f2 4c 99 5d 7c 56 cd 29 5c 30 91 93 6f a2 00 |..L.]|V.)\0..o..|
|
||||
000003d0 c4 97 17 03 03 00 35 81 b3 9e 92 c5 dc 08 b3 f3 |......5.........|
|
||||
000003e0 70 56 52 40 16 d4 75 34 1e e8 b7 ce 5e 5a 7e 47 |pVR@..u4....^Z~G|
|
||||
000003f0 ec d0 75 68 24 06 a6 1b 87 73 6c b0 ff e4 3c 6d |..uh$....sl...<m|
|
||||
00000400 80 7e 02 d3 c1 83 78 e3 82 fe 22 d2 17 03 03 00 |.~....x...".....|
|
||||
00000410 8b 20 dd 38 a2 4d 01 39 2b 53 0a 62 f7 51 9a de |. .8.M.9+S.b.Q..|
|
||||
00000420 10 5e 42 1f a2 13 e5 f5 b0 cb 69 21 eb ac 6e 4d |.^B.......i!..nM|
|
||||
00000430 1d 00 94 e4 29 f1 c6 c0 0c 58 7e ca 99 e5 5d 77 |....)....X~...]w|
|
||||
00000440 c3 3a 23 8e b8 a8 19 6e 35 ec e3 51 61 82 23 2f |.:#....n5..Qa.#/|
|
||||
00000450 3e af 1a e9 6b 4f 43 a9 60 d6 55 d6 75 f5 a6 84 |>...kOC.`.U.u...|
|
||||
00000460 27 64 8b 0f 15 db 95 47 36 b3 14 e0 da a2 21 1e |'d.....G6.....!.|
|
||||
00000470 bf 0d 40 79 c8 6c 3b 9f eb 96 1a cf 9d 09 f7 a9 |..@y.l;.........|
|
||||
00000480 22 e5 13 c4 2a 69 5e 95 d1 40 e5 00 26 20 ae 16 |"...*i^..@..& ..|
|
||||
00000490 55 27 51 a1 c7 e3 2e 1d 32 6c d5 0d |U'Q.....2l..|
|
||||
>>> Flow 3 (client to server)
|
||||
00000000 14 03 03 00 01 01 17 03 03 00 35 71 16 57 df 09 |..........5q.W..|
|
||||
00000010 d7 73 e4 f2 c4 8a 10 b1 d8 73 dc 5b 87 8f 56 51 |.s.......s.[..VQ|
|
||||
00000020 6a ed 61 66 c9 d4 0d fe 28 0c 6f c7 4d ef e6 90 |j.af....(.o.M...|
|
||||
00000030 ba e2 fb c3 c9 4a 94 a2 e5 7f 23 e2 66 2b 4f 9e |.....J....#.f+O.|
|
||||
>>> Flow 4 (server to client)
|
||||
00000000 17 03 03 00 1e 6a c8 6d 0d b6 f7 c8 33 cd c6 25 |.....j.m....3..%|
|
||||
00000010 98 0e bb ac de 69 61 9d ec a3 c0 be 7e 53 44 cb |.....ia.....~SD.|
|
||||
00000020 1f d5 97 17 03 03 00 13 be 18 cc 16 91 88 1e d1 |................|
|
||||
00000030 b5 7c 58 17 fb 39 b2 80 76 7b a8 |.|X..9..v{.|
|
Loading…
Add table
Add a link
Reference in a new issue