Skip to content

Instantly share code, notes, and snippets.

@joneskoo
Created July 12, 2016 20:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joneskoo/254cd57e20acc7035d2c06658297b203 to your computer and use it in GitHub Desktop.
Save joneskoo/254cd57e20acc7035d2c06658297b203 to your computer and use it in GitHub Desktop.
Proof of concept to add KeyLogWriter to go crypto/tls (NSS key log file output)
diff --git a/vendor/crypto/tls/common.go b/vendor/crypto/tls/common.go
index c68ebfe..4ccde9b 100644
--- a/vendor/crypto/tls/common.go
+++ b/vendor/crypto/tls/common.go
@@ -349,6 +349,13 @@ type Config struct {
// be used.
CurvePreferences []CurveID
+ // KeyLogWriter is a debug log stream of all TLS master secrets
+ // as negotiated between client and server.
+ // KeyLogWriter is disabled when nil (default) and must only be
+ // enabled explicitly for debugging as by definition it compromises
+ // the security.
+ KeyLogWriter io.Writer
+
serverInitOnce sync.Once // guards calling (*Config).serverInit
// mutex protects sessionTicketKeys
@@ -562,6 +569,16 @@ func (c *Config) BuildNameToCertificate() {
}
}
+// writeKeyLog logs client random and master secret if logging enabled
+// by setting KeyLogWriter.
+func (c *Config) writeKeyLog(clientRandom, masterSecret []byte) error {
+ if c.KeyLogWriter == nil {
+ return nil
+ }
+ _, err := fmt.Fprintf(c.KeyLogWriter, "CLIENT_RANDOM %x %x\n", clientRandom, masterSecret)
+ return err
+}
+
// A Certificate is a chain of one or more certificates, leaf first.
type Certificate struct {
Certificate [][]byte
diff --git a/vendor/crypto/tls/handshake_client.go b/vendor/crypto/tls/handshake_client.go
index 3c996ac..7c3b328 100644
--- a/vendor/crypto/tls/handshake_client.go
+++ b/vendor/crypto/tls/handshake_client.go
@@ -481,6 +481,10 @@ 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 {
+ c.sendAlert(alertInternalError)
+ return err
+ }
hs.finishedHash.discardHandshakeBuffer()
diff --git a/vendor/crypto/tls/handshake_server.go b/vendor/crypto/tls/handshake_server.go
index e16cddc..691d0b3 100644
--- a/vendor/crypto/tls/handshake_server.go
+++ b/vendor/crypto/tls/handshake_server.go
@@ -459,6 +459,10 @@ func (hs *serverHandshakeState) doFullHandshake() error {
return err
}
hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.clientHello.random, hs.hello.random)
+ if err := config.writeKeyLog(hs.clientHello.random, hs.masterSecret); err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
// If we received a client cert in response to our certificate request message,
// the client will send us a certificateVerifyMsg immediately after the
diff --git a/vendor/net/http/transport.go b/vendor/net/http/transport.go
index 1e3ea11..41aa30e 100644
--- a/vendor/net/http/transport.go
+++ b/vendor/net/http/transport.go
@@ -1745,6 +1745,7 @@ func cloneTLSConfig(cfg *tls.Config) *tls.Config {
MinVersion: cfg.MinVersion,
MaxVersion: cfg.MaxVersion,
CurvePreferences: cfg.CurvePreferences,
+ KeyLogWriter: cfg.KeyLogWriter,
}
}
@@ -1774,5 +1775,6 @@ func cloneTLSClientConfig(cfg *tls.Config) *tls.Config {
MinVersion: cfg.MinVersion,
MaxVersion: cfg.MaxVersion,
CurvePreferences: cfg.CurvePreferences,
+ KeyLogWriter: cfg.KeyLogWriter,
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment