Add tests for SSL_export_keying_material.
Change-Id: Ic4d3ade08aa648ce70ada9981e894b6c1c4197c6
Reviewed-on: https://boringssl-review.googlesource.com/4215
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/test/runner/conn.go b/ssl/test/runner/conn.go
index 90cf01f..0fe34b7 100644
--- a/ssl/test/runner/conn.go
+++ b/ssl/test/runner/conn.go
@@ -37,14 +37,16 @@
handshakeComplete bool
didResume bool // whether this connection was a session resumption
extendedMasterSecret bool // whether this session used an extended master secret
- cipherSuite uint16
+ cipherSuite *cipherSuite
ocspResponse []byte // stapled OCSP response
peerCertificates []*x509.Certificate
// verifiedChains contains the certificate chains that we built, as
// opposed to the ones presented by the server.
verifiedChains [][]*x509.Certificate
// serverName contains the server name indicated by the client, if any.
- serverName string
+ serverName string
+ clientRandom, serverRandom [32]byte
+ masterSecret [48]byte
clientProtocol string
clientProtocolFallback bool
@@ -1276,7 +1278,7 @@
state.DidResume = c.didResume
state.NegotiatedProtocolIsMutual = !c.clientProtocolFallback
state.NegotiatedProtocolFromALPN = c.usedALPN
- state.CipherSuite = c.cipherSuite
+ state.CipherSuite = c.cipherSuite.id
state.PeerCertificates = c.peerCertificates
state.VerifiedChains = c.verifiedChains
state.ServerName = c.serverName
@@ -1310,3 +1312,28 @@
}
return c.peerCertificates[0].VerifyHostname(host)
}
+
+// ExportKeyingMaterial exports keying material from the current connection
+// state, as per RFC 5705.
+func (c *Conn) ExportKeyingMaterial(length int, label, context []byte, useContext bool) ([]byte, error) {
+ c.handshakeMutex.Lock()
+ defer c.handshakeMutex.Unlock()
+ if !c.handshakeComplete {
+ return nil, errors.New("tls: handshake has not yet been performed")
+ }
+
+ seedLen := len(c.clientRandom) + len(c.serverRandom)
+ if useContext {
+ seedLen += 2 + len(context)
+ }
+ seed := make([]byte, 0, seedLen)
+ seed = append(seed, c.clientRandom[:]...)
+ seed = append(seed, c.serverRandom[:]...)
+ if useContext {
+ seed = append(seed, byte(len(context)>>8), byte(len(context)))
+ seed = append(seed, context...)
+ }
+ result := make([]byte, length)
+ prfForVersion(c.vers, c.cipherSuite)(result, c.masterSecret[:], label, seed)
+ return result, nil
+}