Skip to content

Commit de16b32

Browse files
committed
crypto/tls: make ConnectionState.ExportKeyingMaterial a method
The unexported field is hidden from reflect based marshalers, which would break otherwise. Also, make it return an error, as there are multiple reasons it might fail. Fixes golang#27125 Change-Id: I92adade2fe456103d2d5c0315629ca0256953764 Reviewed-on: https://go-review.googlesource.com/130535 Run-TryBot: Filippo Valsorda <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]>
1 parent 90f2fa0 commit de16b32

13 files changed

+432
-24
lines changed

api/go1.11.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
pkg crypto/cipher, func NewGCMWithTagSize(Block, int) (AEAD, error)
22
pkg crypto/rsa, method (*PrivateKey) Size() int
33
pkg crypto/rsa, method (*PublicKey) Size() int
4-
pkg crypto/tls, type ConnectionState struct, ExportKeyingMaterial func(string, []uint8, int) ([]uint8, bool)
4+
pkg crypto/tls, method (*ConnectionState) ExportKeyingMaterial(string, []uint8, int) ([]uint8, error)
55
pkg database/sql, method (IsolationLevel) String() string
66
pkg database/sql, type DBStats struct, Idle int
77
pkg database/sql, type DBStats struct, InUse int

doc/go1.11.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,8 @@ <h3 id="minor_library_changes">Minor changes to the library</h3>
500500
<dd>
501501
<p><!-- CL 85115 -->
502502
<a href="/pkg/crypto/tls/#ConnectionState"><code>ConnectionState</code></a>'s new
503-
<code>ExportKeyingMaterial</code> field allows exporting keying material bound to the
503+
<a href="/pkg/crypto/tls/#ConnectionState.ExportKeyingMaterial"><code>ExportKeyingMaterial</code></a>
504+
method allows exporting keying material bound to the
504505
connection according to RFC 5705.
505506
</p>
506507

src/crypto/tls/common.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -164,11 +164,8 @@ type ConnectionState struct {
164164
SignedCertificateTimestamps [][]byte // SCTs from the server, if any
165165
OCSPResponse []byte // stapled OCSP response from server, if any
166166

167-
// ExportKeyMaterial returns length bytes of exported key material as
168-
// defined in https://tools.ietf.org/html/rfc5705. If context is nil, it is
169-
// not used as part of the seed. If Config.Renegotiation was set to allow
170-
// renegotiation, this function will always return nil, false.
171-
ExportKeyingMaterial func(label string, context []byte, length int) ([]byte, bool)
167+
// ekm is a closure exposed via ExportKeyingMaterial.
168+
ekm func(label string, context []byte, length int) ([]byte, error)
172169

173170
// TLSUnique contains the "tls-unique" channel binding value (see RFC
174171
// 5929, section 3). For resumed sessions this value will be nil
@@ -179,6 +176,14 @@ type ConnectionState struct {
179176
TLSUnique []byte
180177
}
181178

179+
// ExportKeyingMaterial returns length bytes of exported key material in a new
180+
// slice as defined in https://tools.ietf.org/html/rfc5705. If context is nil,
181+
// it is not used as part of the seed. If the connection was set to allow
182+
// renegotiation via Config.Renegotiation, this function will return an error.
183+
func (cs *ConnectionState) ExportKeyingMaterial(label string, context []byte, length int) ([]byte, error) {
184+
return cs.ekm(label, context, length)
185+
}
186+
182187
// ClientAuthType declares the policy the server will follow for
183188
// TLS Client Authentication.
184189
type ClientAuthType int

src/crypto/tls/conn.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ type Conn struct {
5656
// renegotiation is not supported in that case.)
5757
secureRenegotiation bool
5858
// ekm is a closure for exporting keying material.
59-
ekm func(label string, context []byte, length int) ([]byte, bool)
59+
ekm func(label string, context []byte, length int) ([]byte, error)
6060

6161
// clientFinishedIsFirst is true if the client sent the first Finished
6262
// message during the most recent handshake. This is recorded because
@@ -1315,9 +1315,9 @@ func (c *Conn) ConnectionState() ConnectionState {
13151315
}
13161316
}
13171317
if c.config.Renegotiation != RenegotiateNever {
1318-
state.ExportKeyingMaterial = noExportedKeyingMaterial
1318+
state.ekm = noExportedKeyingMaterial
13191319
} else {
1320-
state.ExportKeyingMaterial = c.ekm
1320+
state.ekm = c.ekm
13211321
}
13221322
}
13231323

src/crypto/tls/handshake_client_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -979,6 +979,24 @@ func TestRenegotiateTwiceRejected(t *testing.T) {
979979
runClientTestTLS12(t, test)
980980
}
981981

982+
func TestHandshakeClientExportKeyingMaterial(t *testing.T) {
983+
test := &clientTest{
984+
name: "ExportKeyingMaterial",
985+
command: []string{"openssl", "s_server"},
986+
config: testConfig.Clone(),
987+
validate: func(state ConnectionState) error {
988+
if km, err := state.ExportKeyingMaterial("test", nil, 42); err != nil {
989+
return fmt.Errorf("ExportKeyingMaterial failed: %v", err)
990+
} else if len(km) != 42 {
991+
return fmt.Errorf("Got %d bytes from ExportKeyingMaterial, wanted %d", len(km), 42)
992+
}
993+
return nil
994+
},
995+
}
996+
runClientTestTLS10(t, test)
997+
runClientTestTLS12(t, test)
998+
}
999+
9821000
var hostnameInSNITests = []struct {
9831001
in, out string
9841002
}{

src/crypto/tls/handshake_server_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -998,6 +998,24 @@ func TestFallbackSCSV(t *testing.T) {
998998
runServerTestTLS11(t, test)
999999
}
10001000

1001+
func TestHandshakeServerExportKeyingMaterial(t *testing.T) {
1002+
test := &serverTest{
1003+
name: "ExportKeyingMaterial",
1004+
command: []string{"openssl", "s_client"},
1005+
config: testConfig.Clone(),
1006+
validate: func(state ConnectionState) error {
1007+
if km, err := state.ExportKeyingMaterial("test", nil, 42); err != nil {
1008+
return fmt.Errorf("ExportKeyingMaterial failed: %v", err)
1009+
} else if len(km) != 42 {
1010+
return fmt.Errorf("Got %d bytes from ExportKeyingMaterial, wanted %d", len(km), 42)
1011+
}
1012+
return nil
1013+
},
1014+
}
1015+
runServerTestTLS10(t, test)
1016+
runServerTestTLS12(t, test)
1017+
}
1018+
10011019
func benchmarkHandshakeServer(b *testing.B, cipherSuite uint16, curve CurveID, cert []byte, key crypto.PrivateKey) {
10021020
config := testConfig.Clone()
10031021
config.CipherSuites = []uint16{cipherSuite}

src/crypto/tls/prf.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -347,20 +347,20 @@ func (h *finishedHash) discardHandshakeBuffer() {
347347
}
348348

349349
// noExportedKeyingMaterial is used as a value of
350-
// ConnectionState.ExportKeyingMaterial when renegotation is enabled and thus
350+
// ConnectionState.ekm when renegotation is enabled and thus
351351
// we wish to fail all key-material export requests.
352-
func noExportedKeyingMaterial(label string, context []byte, length int) ([]byte, bool) {
353-
return nil, false
352+
func noExportedKeyingMaterial(label string, context []byte, length int) ([]byte, error) {
353+
return nil, errors.New("crypto/tls: ExportKeyingMaterial is unavailable when renegotiation is enabled")
354354
}
355355

356356
// ekmFromMasterSecret generates exported keying material as defined in
357357
// https://tools.ietf.org/html/rfc5705.
358-
func ekmFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clientRandom, serverRandom []byte) func(string, []byte, int) ([]byte, bool) {
359-
return func(label string, context []byte, length int) ([]byte, bool) {
358+
func ekmFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clientRandom, serverRandom []byte) func(string, []byte, int) ([]byte, error) {
359+
return func(label string, context []byte, length int) ([]byte, error) {
360360
switch label {
361361
case "client finished", "server finished", "master secret", "key expansion":
362362
// These values are reserved and may not be used.
363-
return nil, false
363+
return nil, fmt.Errorf("crypto/tls: reserved ExportKeyingMaterial label: %s", label)
364364
}
365365

366366
seedLen := len(serverRandom) + len(clientRandom)
@@ -374,14 +374,14 @@ func ekmFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clien
374374

375375
if context != nil {
376376
if len(context) >= 1<<16 {
377-
return nil, false
377+
return nil, fmt.Errorf("crypto/tls: ExportKeyingMaterial context too long")
378378
}
379379
seed = append(seed, byte(len(context)>>8), byte(len(context)))
380380
seed = append(seed, context...)
381381
}
382382

383383
keyMaterial := make([]byte, length)
384384
prfForVersion(version, suite)(keyMaterial, masterSecret, []byte(label), seed)
385-
return keyMaterial, true
385+
return keyMaterial, nil
386386
}
387387
}

src/crypto/tls/prf_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,14 @@ func TestKeysFromPreMasterSecret(t *testing.T) {
7070
}
7171

7272
ekm := ekmFromMasterSecret(test.version, test.suite, masterSecret, clientRandom, serverRandom)
73-
contextKeyingMaterial, ok := ekm("label", []byte("context"), 32)
74-
if !ok {
75-
t.Fatalf("ekmFromMasterSecret failed")
73+
contextKeyingMaterial, err := ekm("label", []byte("context"), 32)
74+
if err != nil {
75+
t.Fatalf("ekmFromMasterSecret failed: %v", err)
7676
}
7777

78-
noContextKeyingMaterial, ok := ekm("label", nil, 32)
79-
if !ok {
80-
t.Fatalf("ekmFromMasterSecret failed")
78+
noContextKeyingMaterial, err := ekm("label", nil, 32)
79+
if err != nil {
80+
t.Fatalf("ekmFromMasterSecret failed: %v", err)
8181
}
8282

8383
if hex.EncodeToString(contextKeyingMaterial) != test.contextKeyingMaterial ||
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
>>> Flow 1 (client to server)
2+
00000000 16 03 01 00 95 01 00 00 91 03 03 00 00 00 00 00 |................|
3+
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
4+
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 2c cc a8 |.............,..|
5+
00000030 cc a9 c0 2f c0 2b c0 30 c0 2c c0 27 c0 13 c0 23 |.../.+.0.,.'...#|
6+
00000040 c0 09 c0 14 c0 0a 00 9c 00 9d 00 3c 00 2f 00 35 |...........<./.5|
7+
00000050 c0 12 00 0a 00 05 c0 11 c0 07 01 00 00 3c 00 05 |.............<..|
8+
00000060 00 05 01 00 00 00 00 00 0a 00 0a 00 08 00 1d 00 |................|
9+
00000070 17 00 18 00 19 00 0b 00 02 01 00 00 0d 00 12 00 |................|
10+
00000080 10 04 01 04 03 05 01 05 03 06 01 06 03 02 01 02 |................|
11+
00000090 03 ff 01 00 01 00 00 12 00 00 |..........|
12+
>>> Flow 2 (server to client)
13+
00000000 16 03 01 00 59 02 00 00 55 03 01 67 4f 02 da 87 |....Y...U..gO...|
14+
00000010 52 30 9a f0 3b e0 63 42 bf 6c 18 58 00 06 70 cf |R0..;.cB.l.X..p.|
15+
00000020 2a 27 5a 00 a7 57 49 fe 03 dd 3b 20 7c 2c 74 00 |*'Z..WI...; |,t.|
16+
00000030 6e b2 35 ca 1b b5 8c 46 f7 78 ab 11 92 43 8c f6 |n.5....F.x...C..|
17+
00000040 97 d3 b8 07 4c 9c 95 2b 08 fe e8 82 c0 13 00 00 |....L..+........|
18+
00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................|
19+
00000060 01 02 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 |..Y...U..R..O0..|
20+
00000070 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d |K0..............|
21+
00000080 3f e2 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 |?.[..0...*.H....|
22+
00000090 01 0b 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 |....0.1.0...U...|
23+
000000a0 02 47 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f |.Go1.0...U....Go|
24+
000000b0 20 52 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 | Root0...1601010|
25+
000000c0 30 30 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 |00000Z..25010100|
26+
000000d0 30 30 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a |0000Z0.1.0...U..|
27+
000000e0 13 02 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 |..Go1.0...U....G|
28+
000000f0 6f 30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 |o0..0...*.H.....|
29+
00000100 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 |.......0.......F|
30+
00000110 7d 93 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 |}...'.H..(!.~...|
31+
00000120 5d fe 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 |]..RE.z6G....B[.|
32+
00000130 81 c0 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 |[email protected]..+...|
33+
00000140 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b |..g....."8.J.ts+|
34+
00000150 c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c |.4......t{.X.la<|
35+
00000160 c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d |..A..++$#w[.;.u]|
36+
00000170 ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b |. T..c...$....P.|
37+
00000180 aa b6 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 |...C...ub...R...|
38+
00000190 01 00 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f |......0..0...U..|
39+
000001a0 01 01 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 |.........0...U.%|
40+
000001b0 04 16 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 |..0...+.........|
41+
000001c0 2b 06 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 |+.......0...U...|
42+
000001d0 01 ff 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 |....0.0...U.....|
43+
000001e0 10 9f 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f |.....CC>I..m....|
44+
000001f0 60 30 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 |`0...U.#..0...H.|
45+
00000200 49 4d 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 |IM.~.1......n{0.|
46+
00000210 06 03 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 |..U....0...examp|
47+
00000220 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 |le.golang0...*.H|
48+
00000230 86 f7 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 |.............0.@|
49+
00000240 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 |+[P.a...SX...(.X|
50+
00000250 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d |..8....1Z..f=C.-|
51+
00000260 d9 0b f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c |...... d8.$:....|
52+
00000270 7d b7 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 |}.@ ._...a..v...|
53+
00000280 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 |...\.....l..s..C|
54+
00000290 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d |[email protected]+.|
55+
000002a0 ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db |..F..M...>...B..|
56+
000002b0 fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 01 00 |.=.`.\!.;.......|
57+
000002c0 aa 0c 00 00 a6 03 00 1d 20 a0 0e 1d 92 2d b0 a5 |........ ....-..|
58+
000002d0 f0 ab d5 79 a0 bb 12 ff 23 46 bc 27 0d 73 ff 3e |...y....#F.'.s.>|
59+
000002e0 ad 06 d6 57 6b c2 11 76 2d 00 80 77 bf cd 2b cb |...Wk..v-..w..+.|
60+
000002f0 66 c2 fa 30 ed b1 e7 44 79 1b 28 e6 89 62 17 07 |f..0...Dy.(..b..|
61+
00000300 82 c1 5f dc b2 20 4e 42 ed 54 d6 28 3a 2a e3 a3 |.._.. NB.T.(:*..|
62+
00000310 79 06 e3 08 3c c1 3e b9 c6 41 71 2f d0 29 82 36 |y...<.>..Aq/.).6|
63+
00000320 ef 8d 67 c8 77 d0 32 d3 33 5f 77 92 dd 98 bb 03 |..g.w.2.3_w.....|
64+
00000330 cc 0b a6 75 8f 4a 1d f5 6e 1b 06 5b 4a 8b 16 a4 |...u.J..n..[J...|
65+
00000340 c1 ce 11 9d 70 bc 62 7f 58 a5 86 76 91 3d 3a 04 |....p.b.X..v.=:.|
66+
00000350 93 92 89 42 9b a7 7d 9d 75 25 6d 98 f3 e6 68 7e |...B..}.u%m...h~|
67+
00000360 a8 c6 b1 db a7 95 63 39 94 5a 05 16 03 01 00 04 |......c9.Z......|
68+
00000370 0e 00 00 00 |....|
69+
>>> Flow 3 (client to server)
70+
00000000 16 03 01 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.|
71+
00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....|
72+
00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 01 00 01 01 |....._X.;t......|
73+
00000030 16 03 01 00 30 73 ad 46 66 66 e8 bd 44 e4 bf 71 |....0s.Fff..D..q|
74+
00000040 a2 d4 87 e2 4b a3 4a b2 a0 ca ed ac 61 8c 1e 7f |....K.J.....a...|
75+
00000050 68 bf 6f 98 b1 fb 10 1a 5a e6 36 61 91 ac c4 55 |h.o.....Z.6a...U|
76+
00000060 a3 4d 69 66 6e |.Mifn|
77+
>>> Flow 4 (server to client)
78+
00000000 14 03 01 00 01 01 16 03 01 00 30 57 aa 5c d5 dc |..........0W.\..|
79+
00000010 83 4b 23 80 34 4e 36 e8 d6 f3 40 7e ae 12 44 a6 |.K#.4N6...@~..D.|
80+
00000020 c7 48 99 99 0a 85 3c 59 75 32 4e 88 3c 98 a0 23 |.H....<Yu2N.<..#|
81+
00000030 78 c8 a7 2b 43 25 6a ad d1 78 54 |x..+C%j..xT|
82+
>>> Flow 5 (client to server)
83+
00000000 17 03 01 00 20 e4 9c f4 fa 6b e8 85 87 6f 20 45 |.... ....k...o E|
84+
00000010 71 d3 e2 9e e3 14 2a 7c 64 e8 11 53 fd 93 c1 4a |q.....*|d..S...J|
85+
00000020 1b 94 f8 48 78 17 03 01 00 20 b9 41 32 1d e8 70 |...Hx.... .A2..p|
86+
00000030 87 5f 2c c6 67 d1 77 3c 30 83 0c 66 35 eb 1d da |._,.g.w<0..f5...|
87+
00000040 6e dd 30 ff 82 05 5f f1 cd e7 15 03 01 00 20 6c |n.0..._....... l|
88+
00000050 47 82 5e 90 5b 84 15 78 05 bd 48 63 d5 46 2f 7e |G.^.[..x..Hc.F/~|
89+
00000060 83 49 ce 3c 0f 04 92 52 5b e7 d5 cf 2c bf 65 |.I.<...R[...,.e|

0 commit comments

Comments
 (0)