Implement exporters for TLS 1.3 in Go.
Tested against the C code. Change-Id: I62639e1e46cd4f57625be5d4ff7f6902b318c278 Reviewed-on: https://boringssl-review.googlesource.com/8768 Reviewed-by: Steven Valdez <svaldez@google.com> Reviewed-by: David Benjamin <davidben@google.com>
This commit is contained in:
parent
c87ebdec57
commit
97a0a08293
@ -55,7 +55,7 @@ type Conn struct {
|
|||||||
peerSignatureAlgorithm signatureAlgorithm
|
peerSignatureAlgorithm signatureAlgorithm
|
||||||
|
|
||||||
clientRandom, serverRandom [32]byte
|
clientRandom, serverRandom [32]byte
|
||||||
masterSecret [48]byte
|
exporterSecret []byte
|
||||||
|
|
||||||
clientProtocol string
|
clientProtocol string
|
||||||
clientProtocolFallback bool
|
clientProtocolFallback bool
|
||||||
@ -1527,6 +1527,12 @@ func (c *Conn) ExportKeyingMaterial(length int, label, context []byte, useContex
|
|||||||
return nil, errors.New("tls: handshake has not yet been performed")
|
return nil, errors.New("tls: handshake has not yet been performed")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if enableTLS13Handshake && c.vers >= VersionTLS13 {
|
||||||
|
// TODO(davidben): What should we do with useContext? See
|
||||||
|
// https://github.com/tlswg/tls13-spec/issues/546
|
||||||
|
return hkdfExpandLabel(c.cipherSuite.hash(), c.exporterSecret, label, context, length), nil
|
||||||
|
}
|
||||||
|
|
||||||
seedLen := len(c.clientRandom) + len(c.serverRandom)
|
seedLen := len(c.clientRandom) + len(c.serverRandom)
|
||||||
if useContext {
|
if useContext {
|
||||||
seedLen += 2 + len(context)
|
seedLen += 2 + len(context)
|
||||||
@ -1539,7 +1545,7 @@ func (c *Conn) ExportKeyingMaterial(length int, label, context []byte, useContex
|
|||||||
seed = append(seed, context...)
|
seed = append(seed, context...)
|
||||||
}
|
}
|
||||||
result := make([]byte, length)
|
result := make([]byte, length)
|
||||||
prfForVersion(c.vers, c.cipherSuite)(result, c.masterSecret[:], label, seed)
|
prfForVersion(c.vers, c.cipherSuite)(result, c.exporterSecret, label, seed)
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,13 +410,13 @@ NextCipherSuite:
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.didResume = isResume
|
c.didResume = isResume
|
||||||
|
c.exporterSecret = hs.masterSecret
|
||||||
}
|
}
|
||||||
|
|
||||||
c.handshakeComplete = true
|
c.handshakeComplete = true
|
||||||
c.cipherSuite = suite
|
c.cipherSuite = suite
|
||||||
copy(c.clientRandom[:], hs.hello.random)
|
copy(c.clientRandom[:], hs.hello.random)
|
||||||
copy(c.serverRandom[:], hs.serverHello.random)
|
copy(c.serverRandom[:], hs.serverHello.random)
|
||||||
copy(c.masterSecret[:], hs.masterSecret)
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -644,6 +644,7 @@ func (hs *clientHandshakeState) doTLS13Handshake() error {
|
|||||||
if c.config.Bugs.BadFinished {
|
if c.config.Bugs.BadFinished {
|
||||||
finished.verifyData[0]++
|
finished.verifyData[0]++
|
||||||
}
|
}
|
||||||
|
hs.writeClientHash(finished.marshal())
|
||||||
c.writeRecord(recordTypeHandshake, finished.marshal())
|
c.writeRecord(recordTypeHandshake, finished.marshal())
|
||||||
c.flushHandshake()
|
c.flushHandshake()
|
||||||
|
|
||||||
@ -651,9 +652,9 @@ func (hs *clientHandshakeState) doTLS13Handshake() error {
|
|||||||
c.out.updateKeys(deriveTrafficAEAD(c.vers, hs.suite, trafficSecret, applicationPhase, clientWrite), c.vers)
|
c.out.updateKeys(deriveTrafficAEAD(c.vers, hs.suite, trafficSecret, applicationPhase, clientWrite), c.vers)
|
||||||
c.in.updateKeys(deriveTrafficAEAD(c.vers, hs.suite, trafficSecret, applicationPhase, serverWrite), c.vers)
|
c.in.updateKeys(deriveTrafficAEAD(c.vers, hs.suite, trafficSecret, applicationPhase, serverWrite), c.vers)
|
||||||
|
|
||||||
// TODO(davidben): Derive and save the exporter master secret for key exporters. Swap out the masterSecret field.
|
|
||||||
// TODO(davidben): Derive and save the resumption master secret for receiving tickets.
|
// TODO(davidben): Derive and save the resumption master secret for receiving tickets.
|
||||||
// TODO(davidben): Save the traffic secret for KeyUpdate.
|
// TODO(davidben): Save the traffic secret for KeyUpdate.
|
||||||
|
c.exporterSecret = hs.finishedHash.deriveSecret(masterSecret, exporterLabel)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,11 +120,12 @@ func (c *Conn) serverHandshake() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.exporterSecret = hs.masterSecret
|
||||||
}
|
}
|
||||||
c.handshakeComplete = true
|
c.handshakeComplete = true
|
||||||
copy(c.clientRandom[:], hs.clientHello.random)
|
copy(c.clientRandom[:], hs.clientHello.random)
|
||||||
copy(c.serverRandom[:], hs.hello.random)
|
copy(c.serverRandom[:], hs.hello.random)
|
||||||
copy(c.masterSecret[:], hs.masterSecret)
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -544,15 +545,16 @@ Curves:
|
|||||||
c.sendAlert(alertHandshakeFailure)
|
c.sendAlert(alertHandshakeFailure)
|
||||||
return errors.New("tls: client's Finished message was incorrect")
|
return errors.New("tls: client's Finished message was incorrect")
|
||||||
}
|
}
|
||||||
|
hs.writeClientHash(clientFinished.marshal())
|
||||||
|
|
||||||
// Switch to application data keys.
|
// Switch to application data keys.
|
||||||
c.out.updateKeys(deriveTrafficAEAD(c.vers, hs.suite, trafficSecret, applicationPhase, serverWrite), c.vers)
|
c.out.updateKeys(deriveTrafficAEAD(c.vers, hs.suite, trafficSecret, applicationPhase, serverWrite), c.vers)
|
||||||
c.in.updateKeys(deriveTrafficAEAD(c.vers, hs.suite, trafficSecret, applicationPhase, clientWrite), c.vers)
|
c.in.updateKeys(deriveTrafficAEAD(c.vers, hs.suite, trafficSecret, applicationPhase, clientWrite), c.vers)
|
||||||
|
|
||||||
// TODO(davidben): Derive and save the exporter master secret for key exporters. Swap out the masterSecret field.
|
|
||||||
// TODO(davidben): Derive and save the resumption master secret for receiving tickets.
|
// TODO(davidben): Derive and save the resumption master secret for receiving tickets.
|
||||||
// TODO(davidben): Save the traffic secret for KeyUpdate.
|
// TODO(davidben): Save the traffic secret for KeyUpdate.
|
||||||
c.cipherSuite = hs.suite
|
c.cipherSuite = hs.suite
|
||||||
|
c.exporterSecret = hs.finishedHash.deriveSecret(masterSecret, exporterLabel)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user