mirror of
https://github.com/golang/go
synced 2024-11-12 08:20:22 -07:00
crypto/tls: implement TLS 1.3 KeyLogWriter support
Also, add support for the SSLKEYLOGFILE environment variable to the tests, to simplify debugging of unexpected failures. Updates #9671 Change-Id: I20a34a5824f083da93097b793d51e796d6eb302b Reviewed-on: https://go-review.googlesource.com/c/147417 Run-TryBot: Filippo Valsorda <filippo@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
This commit is contained in:
parent
14560da7e4
commit
29b01d556d
@ -853,14 +853,20 @@ func (c *Config) BuildNameToCertificate() {
|
||||
}
|
||||
}
|
||||
|
||||
// writeKeyLog logs client random and master secret if logging was enabled by
|
||||
// setting c.KeyLogWriter.
|
||||
func (c *Config) writeKeyLog(clientRandom, masterSecret []byte) error {
|
||||
const (
|
||||
keyLogLabelTLS12 = "CLIENT_RANDOM"
|
||||
keyLogLabelClientHandshake = "CLIENT_HANDSHAKE_TRAFFIC_SECRET"
|
||||
keyLogLabelServerHandshake = "SERVER_HANDSHAKE_TRAFFIC_SECRET"
|
||||
keyLogLabelClientTraffic = "CLIENT_TRAFFIC_SECRET_0"
|
||||
keyLogLabelServerTraffic = "SERVER_TRAFFIC_SECRET_0"
|
||||
)
|
||||
|
||||
func (c *Config) writeKeyLog(label string, clientRandom, secret []byte) error {
|
||||
if c.KeyLogWriter == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
logLine := []byte(fmt.Sprintf("CLIENT_RANDOM %x %x\n", clientRandom, masterSecret))
|
||||
logLine := []byte(fmt.Sprintf("%s %x %x\n", label, clientRandom, secret))
|
||||
|
||||
writerMutex.Lock()
|
||||
_, err := c.KeyLogWriter.Write(logLine)
|
||||
|
@ -524,7 +524,7 @@ func (hs *clientHandshakeState) doFullHandshake() error {
|
||||
}
|
||||
|
||||
hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.hello.random, hs.serverHello.random)
|
||||
if err := c.config.writeKeyLog(hs.hello.random, hs.masterSecret); err != nil {
|
||||
if err := c.config.writeKeyLog(keyLogLabelTLS12, hs.hello.random, hs.masterSecret); err != nil {
|
||||
c.sendAlert(alertInternalError)
|
||||
return errors.New("tls: failed to write to key log: " + err.Error())
|
||||
}
|
||||
|
@ -968,6 +968,49 @@ func TestKeyLog(t *testing.T) {
|
||||
checkKeylogLine("server", serverBuf.String())
|
||||
}
|
||||
|
||||
func TestKeyLogTLS13(t *testing.T) {
|
||||
var serverBuf, clientBuf bytes.Buffer
|
||||
|
||||
clientConfig := testConfig.Clone()
|
||||
clientConfig.KeyLogWriter = &clientBuf
|
||||
clientConfig.MaxVersion = VersionTLS13
|
||||
|
||||
serverConfig := testConfig.Clone()
|
||||
serverConfig.KeyLogWriter = &serverBuf
|
||||
serverConfig.MaxVersion = VersionTLS13
|
||||
|
||||
c, s := localPipe(t)
|
||||
done := make(chan bool)
|
||||
|
||||
go func() {
|
||||
defer close(done)
|
||||
|
||||
if err := Server(s, serverConfig).Handshake(); err != nil {
|
||||
t.Errorf("server: %s", err)
|
||||
return
|
||||
}
|
||||
s.Close()
|
||||
}()
|
||||
|
||||
if err := Client(c, clientConfig).Handshake(); err != nil {
|
||||
t.Fatalf("client: %s", err)
|
||||
}
|
||||
|
||||
c.Close()
|
||||
<-done
|
||||
|
||||
checkKeylogLines := func(side, loggedLines string) {
|
||||
loggedLines = strings.TrimSpace(loggedLines)
|
||||
lines := strings.Split(loggedLines, "\n")
|
||||
if len(lines) != 4 {
|
||||
t.Errorf("Expected the %s to log 4 lines, got %d", side, len(lines))
|
||||
}
|
||||
}
|
||||
|
||||
checkKeylogLines("client", clientBuf.String())
|
||||
checkKeylogLines("server", serverBuf.String())
|
||||
}
|
||||
|
||||
func TestHandshakeClientALPNMatch(t *testing.T) {
|
||||
config := testConfig.Clone()
|
||||
config.NextProtos = []string{"proto2", "proto1"}
|
||||
|
@ -269,6 +269,17 @@ func (hs *clientHandshakeStateTLS13) establishHandshakeKeys() error {
|
||||
serverHandshakeTrafficLabel, hs.transcript)
|
||||
c.in.setTrafficSecret(hs.suite, serverSecret)
|
||||
|
||||
err := c.config.writeKeyLog(keyLogLabelClientHandshake, hs.hello.random, clientSecret)
|
||||
if err != nil {
|
||||
c.sendAlert(alertInternalError)
|
||||
return err
|
||||
}
|
||||
err = c.config.writeKeyLog(keyLogLabelServerHandshake, hs.hello.random, serverSecret)
|
||||
if err != nil {
|
||||
c.sendAlert(alertInternalError)
|
||||
return err
|
||||
}
|
||||
|
||||
hs.masterSecret = hs.suite.extract(nil,
|
||||
hs.suite.deriveSecret(handshakeSecret, "derived", nil))
|
||||
|
||||
@ -409,6 +420,17 @@ func (hs *clientHandshakeStateTLS13) readServerFinished() error {
|
||||
serverApplicationTrafficLabel, hs.transcript)
|
||||
c.in.setTrafficSecret(hs.suite, serverSecret)
|
||||
|
||||
err = c.config.writeKeyLog(keyLogLabelClientTraffic, hs.hello.random, hs.trafficSecret)
|
||||
if err != nil {
|
||||
c.sendAlert(alertInternalError)
|
||||
return err
|
||||
}
|
||||
err = c.config.writeKeyLog(keyLogLabelServerTraffic, hs.hello.random, serverSecret)
|
||||
if err != nil {
|
||||
c.sendAlert(alertInternalError)
|
||||
return err
|
||||
}
|
||||
|
||||
c.ekm = hs.suite.exportKeyingMaterial(hs.masterSecret, hs.transcript)
|
||||
|
||||
return nil
|
||||
|
@ -528,7 +528,7 @@ func (hs *serverHandshakeState) doFullHandshake() error {
|
||||
return err
|
||||
}
|
||||
hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.clientHello.random, hs.hello.random)
|
||||
if err := c.config.writeKeyLog(hs.clientHello.random, hs.masterSecret); err != nil {
|
||||
if err := c.config.writeKeyLog(keyLogLabelTLS12, hs.clientHello.random, hs.masterSecret); err != nil {
|
||||
c.sendAlert(alertInternalError)
|
||||
return err
|
||||
}
|
||||
|
@ -63,6 +63,13 @@ func init() {
|
||||
testConfig.Certificates[1].Certificate = [][]byte{testSNICertificate}
|
||||
testConfig.Certificates[1].PrivateKey = testRSAPrivateKey
|
||||
testConfig.BuildNameToCertificate()
|
||||
if keyFile := os.Getenv("SSLKEYLOGFILE"); keyFile != "" {
|
||||
f, err := os.OpenFile(keyFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
panic("failed to open SSLKEYLOGFILE: " + err.Error())
|
||||
}
|
||||
testConfig.KeyLogWriter = f
|
||||
}
|
||||
}
|
||||
|
||||
func testClientHello(t *testing.T, serverConfig *Config, m handshakeMessage) {
|
||||
|
@ -336,6 +336,17 @@ func (hs *serverHandshakeStateTLS13) sendServerParameters() error {
|
||||
serverHandshakeTrafficLabel, hs.transcript)
|
||||
c.out.setTrafficSecret(hs.suite, serverSecret)
|
||||
|
||||
err := c.config.writeKeyLog(keyLogLabelClientHandshake, hs.clientHello.random, clientSecret)
|
||||
if err != nil {
|
||||
c.sendAlert(alertInternalError)
|
||||
return err
|
||||
}
|
||||
err = c.config.writeKeyLog(keyLogLabelServerHandshake, hs.clientHello.random, serverSecret)
|
||||
if err != nil {
|
||||
c.sendAlert(alertInternalError)
|
||||
return err
|
||||
}
|
||||
|
||||
encryptedExtensions := new(encryptedExtensionsMsg)
|
||||
|
||||
if len(hs.clientHello.alpnProtocols) > 0 {
|
||||
@ -426,6 +437,17 @@ func (hs *serverHandshakeStateTLS13) sendServerFinished() error {
|
||||
serverApplicationTrafficLabel, hs.transcript)
|
||||
c.out.setTrafficSecret(hs.suite, serverSecret)
|
||||
|
||||
err := c.config.writeKeyLog(keyLogLabelClientTraffic, hs.clientHello.random, hs.trafficSecret)
|
||||
if err != nil {
|
||||
c.sendAlert(alertInternalError)
|
||||
return err
|
||||
}
|
||||
err = c.config.writeKeyLog(keyLogLabelServerTraffic, hs.clientHello.random, serverSecret)
|
||||
if err != nil {
|
||||
c.sendAlert(alertInternalError)
|
||||
return err
|
||||
}
|
||||
|
||||
c.ekm = hs.suite.exportKeyingMaterial(masterSecret, hs.transcript)
|
||||
|
||||
return nil
|
||||
|
Loading…
Reference in New Issue
Block a user