forked from quic-go/quic-go
retrieve the handshake write key when receiving the ServerHello
This commit is contained in:
40
vendor/github.com/marten-seemann/qtls/13.go
generated
vendored
40
vendor/github.com/marten-seemann/qtls/13.go
generated
vendored
@@ -116,9 +116,9 @@ func (ks *keySchedule13) setSecret(secret []byte) {
|
||||
salt := ks.secret
|
||||
if salt != nil {
|
||||
h0 := hash.New().Sum(nil)
|
||||
salt = HkdfExpandLabel(hash, salt, h0, "derived", hash.Size())
|
||||
salt = hkdfExpandLabel(hash, salt, h0, "derived", hash.Size())
|
||||
}
|
||||
ks.secret = HkdfExtract(hash, secret, salt)
|
||||
ks.secret = hkdfExtract(hash, secret, salt)
|
||||
}
|
||||
|
||||
// Depending on role returns pair of key variant to be used by
|
||||
@@ -168,7 +168,7 @@ func (ks *keySchedule13) deriveSecret(secretLabel secretLabel) []byte {
|
||||
ks.handshakeCtx = ks.transcriptHash.Sum(nil)
|
||||
}
|
||||
hash := hashForSuite(ks.suite)
|
||||
secret := HkdfExpandLabel(hash, ks.secret, ks.handshakeCtx, label, hash.Size())
|
||||
secret := hkdfExpandLabel(hash, ks.secret, ks.handshakeCtx, label, hash.Size())
|
||||
if keylogType != "" && ks.config != nil {
|
||||
ks.config.writeKeyLog(keylogType, ks.clientRandom, secret)
|
||||
}
|
||||
@@ -177,8 +177,8 @@ func (ks *keySchedule13) deriveSecret(secretLabel secretLabel) []byte {
|
||||
|
||||
func (ks *keySchedule13) prepareCipher(trafficSecret []byte) cipher.AEAD {
|
||||
hash := hashForSuite(ks.suite)
|
||||
key := HkdfExpandLabel(hash, trafficSecret, nil, "key", ks.suite.keyLen)
|
||||
iv := HkdfExpandLabel(hash, trafficSecret, nil, "iv", ks.suite.ivLen)
|
||||
key := hkdfExpandLabel(hash, trafficSecret, nil, "key", ks.suite.keyLen)
|
||||
iv := hkdfExpandLabel(hash, trafficSecret, nil, "iv", ks.suite.ivLen)
|
||||
return ks.suite.aead(key, iv)
|
||||
}
|
||||
|
||||
@@ -254,10 +254,11 @@ CurvePreferenceLoop:
|
||||
hs.keySchedule.setSecret(ecdheSecret)
|
||||
hs.hsClientTrafficSecret = hs.keySchedule.deriveSecret(secretHandshakeClient)
|
||||
hsServerTrafficSecret := hs.keySchedule.deriveSecret(secretHandshakeServer)
|
||||
c.out.exportKey(hs.keySchedule.suite, hsServerTrafficSecret)
|
||||
c.out.setKey(c.vers, hs.keySchedule.suite, hsServerTrafficSecret)
|
||||
|
||||
serverFinishedKey := HkdfExpandLabel(hash, hsServerTrafficSecret, nil, "finished", hashSize)
|
||||
hs.clientFinishedKey = HkdfExpandLabel(hash, hs.hsClientTrafficSecret, nil, "finished", hashSize)
|
||||
serverFinishedKey := hkdfExpandLabel(hash, hsServerTrafficSecret, nil, "finished", hashSize)
|
||||
hs.clientFinishedKey = hkdfExpandLabel(hash, hs.hsClientTrafficSecret, nil, "finished", hashSize)
|
||||
|
||||
// EncryptedExtensions
|
||||
hs.keySchedule.write(hs.hello13Enc.marshal())
|
||||
@@ -296,6 +297,7 @@ CurvePreferenceLoop:
|
||||
|
||||
hs.keySchedule.setSecret(nil) // derive master secret
|
||||
serverAppTrafficSecret := hs.keySchedule.deriveSecret(secretApplicationServer)
|
||||
c.out.exportKey(hs.keySchedule.suite, serverAppTrafficSecret)
|
||||
c.out.setKey(c.vers, hs.keySchedule.suite, serverAppTrafficSecret)
|
||||
|
||||
if c.hand.Len() > 0 {
|
||||
@@ -303,9 +305,11 @@ CurvePreferenceLoop:
|
||||
}
|
||||
hs.appClientTrafficSecret = hs.keySchedule.deriveSecret(secretApplicationClient)
|
||||
if hs.hello13Enc.earlyData {
|
||||
c.in.exportKey(hs.keySchedule.suite, earlyClientTrafficSecret)
|
||||
c.in.setKey(c.vers, hs.keySchedule.suite, earlyClientTrafficSecret)
|
||||
c.phase = readingEarlyData
|
||||
} else {
|
||||
c.in.exportKey(hs.keySchedule.suite, hs.hsClientTrafficSecret)
|
||||
c.in.setKey(c.vers, hs.keySchedule.suite, hs.hsClientTrafficSecret)
|
||||
if hs.clientHello.earlyData {
|
||||
c.phase = discardingEarlyData
|
||||
@@ -418,6 +422,7 @@ func (hs *serverHandshakeState) readClientFinished13(hasConfirmLock bool) error
|
||||
if c.hand.Len() > 0 {
|
||||
return c.sendAlert(alertUnexpectedMessage)
|
||||
}
|
||||
c.in.exportKey(hs.keySchedule.suite, hs.appClientTrafficSecret)
|
||||
c.in.setKey(c.vers, hs.keySchedule.suite, hs.appClientTrafficSecret)
|
||||
c.in.traceErr, c.out.traceErr = nil, nil
|
||||
c.phase = handshakeConfirmed
|
||||
@@ -514,6 +519,7 @@ func (c *Conn) handleEndOfEarlyData() error {
|
||||
}
|
||||
c.hs.keySchedule.write(endOfEarlyData.marshal())
|
||||
c.phase = waitingClientFinished
|
||||
c.in.exportKey(c.hs.keySchedule.suite, c.hs.hsClientTrafficSecret)
|
||||
c.in.setKey(c.vers, c.hs.keySchedule.suite, c.hs.hsClientTrafficSecret)
|
||||
return nil
|
||||
}
|
||||
@@ -618,6 +624,10 @@ func (c *Conn) deriveDHESecret(ks keyShare, secretKey []byte) []byte {
|
||||
|
||||
// HkdfExpandLabel HKDF expands a label
|
||||
func HkdfExpandLabel(hash crypto.Hash, secret, hashValue []byte, label string, L int) []byte {
|
||||
return hkdfExpandLabel(hash, secret, hashValue, label, L)
|
||||
}
|
||||
|
||||
func hkdfExpandLabel(hash crypto.Hash, secret, hashValue []byte, label string, L int) []byte {
|
||||
prefix := "tls13 "
|
||||
hkdfLabel := make([]byte, 4+len(prefix)+len(label)+len(hashValue))
|
||||
hkdfLabel[0] = byte(L >> 8)
|
||||
@@ -710,7 +720,7 @@ func (hs *serverHandshakeState) checkPSK() (isResumed bool, alert alert) {
|
||||
|
||||
hs.keySchedule.setSecret(s.pskSecret)
|
||||
binderKey := hs.keySchedule.deriveSecret(secretResumptionPskBinder)
|
||||
binderFinishedKey := HkdfExpandLabel(hash, binderKey, nil, "finished", hashSize)
|
||||
binderFinishedKey := hkdfExpandLabel(hash, binderKey, nil, "finished", hashSize)
|
||||
chHash := hash.New()
|
||||
chHash.Write(hs.clientHello.rawTruncated)
|
||||
expectedBinder := hmacOfSum(hash, chHash, binderFinishedKey)
|
||||
@@ -781,7 +791,7 @@ func (hs *serverHandshakeState) sendSessionTicket13() error {
|
||||
// tickets might have the same PSK which could be a problem if
|
||||
// one of them is compromised.
|
||||
ticketNonce := []byte{byte(i)}
|
||||
sessionState.pskSecret = HkdfExpandLabel(hash, resumptionMasterSecret, ticketNonce, "resumption", hash.Size())
|
||||
sessionState.pskSecret = hkdfExpandLabel(hash, resumptionMasterSecret, ticketNonce, "resumption", hash.Size())
|
||||
ticket := sessionState.marshal()
|
||||
var err error
|
||||
if c.config.SessionTicketSealer != nil {
|
||||
@@ -1006,13 +1016,17 @@ func (hs *clientHandshakeState) doTLS13Handshake() error {
|
||||
c.sendAlert(alertUnexpectedMessage)
|
||||
return errors.New("tls: unexpected data after Server Hello")
|
||||
}
|
||||
// Do not change the sender key yet, the server must authenticate first.
|
||||
serverHandshakeSecret := hs.keySchedule.deriveSecret(secretHandshakeServer)
|
||||
c.in.exportKey(hs.keySchedule.suite, serverHandshakeSecret)
|
||||
// Already the sender key yet, when using an alternative record layer.
|
||||
// QUIC needs the handshake write key in order to acknowlege Handshake packets.
|
||||
c.out.exportKey(hs.keySchedule.suite, clientHandshakeSecret)
|
||||
// Do not change the sender key yet, the server must authenticate first.
|
||||
c.in.setKey(c.vers, hs.keySchedule.suite, serverHandshakeSecret)
|
||||
|
||||
// Calculate MAC key for Finished messages.
|
||||
serverFinishedKey := HkdfExpandLabel(hash, serverHandshakeSecret, nil, "finished", hashSize)
|
||||
clientFinishedKey := HkdfExpandLabel(hash, clientHandshakeSecret, nil, "finished", hashSize)
|
||||
serverFinishedKey := hkdfExpandLabel(hash, serverHandshakeSecret, nil, "finished", hashSize)
|
||||
clientFinishedKey := hkdfExpandLabel(hash, clientHandshakeSecret, nil, "finished", hashSize)
|
||||
|
||||
msg, err := c.readHandshake()
|
||||
if err != nil {
|
||||
@@ -1155,11 +1169,13 @@ func (hs *clientHandshakeState) doTLS13Handshake() error {
|
||||
|
||||
// Handshake done, set application traffic secret
|
||||
// TODO store initial traffic secret key for KeyUpdate GH #85
|
||||
c.out.exportKey(hs.keySchedule.suite, clientAppTrafficSecret)
|
||||
c.out.setKey(c.vers, hs.keySchedule.suite, clientAppTrafficSecret)
|
||||
if c.hand.Len() > 0 {
|
||||
c.sendAlert(alertUnexpectedMessage)
|
||||
return errors.New("tls: unexpected data after handshake")
|
||||
}
|
||||
c.in.exportKey(hs.keySchedule.suite, serverAppTrafficSecret)
|
||||
c.in.setKey(c.vers, hs.keySchedule.suite, serverAppTrafficSecret)
|
||||
return nil
|
||||
}
|
||||
|
||||
11
vendor/github.com/marten-seemann/qtls/conn.go
generated
vendored
11
vendor/github.com/marten-seemann/qtls/conn.go
generated
vendored
@@ -234,15 +234,20 @@ func (hc *halfConn) changeCipherSpec() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (hc *halfConn) setKey(version uint16, suite *cipherSuite, trafficSecret []byte) {
|
||||
func (hc *halfConn) exportKey(suite *cipherSuite, trafficSecret []byte) {
|
||||
if hc.setKeyCallback != nil {
|
||||
hc.setKeyCallback(&CipherSuite{*suite}, trafficSecret)
|
||||
}
|
||||
}
|
||||
|
||||
func (hc *halfConn) setKey(version uint16, suite *cipherSuite, trafficSecret []byte) {
|
||||
if hc.setKeyCallback != nil {
|
||||
return
|
||||
}
|
||||
hc.version = version
|
||||
hash := hashForSuite(suite)
|
||||
key := HkdfExpandLabel(hash, trafficSecret, nil, "key", suite.keyLen)
|
||||
iv := HkdfExpandLabel(hash, trafficSecret, nil, "iv", suite.ivLen)
|
||||
key := hkdfExpandLabel(hash, trafficSecret, nil, "key", suite.keyLen)
|
||||
iv := hkdfExpandLabel(hash, trafficSecret, nil, "iv", suite.ivLen)
|
||||
hc.cipher = suite.aead(key, iv)
|
||||
for i := range hc.seq {
|
||||
hc.seq[i] = 0
|
||||
|
||||
4
vendor/github.com/marten-seemann/qtls/hkdf.go
generated
vendored
4
vendor/github.com/marten-seemann/qtls/hkdf.go
generated
vendored
@@ -47,6 +47,10 @@ func hkdfExpand(hash crypto.Hash, prk, info []byte, l int) []byte {
|
||||
|
||||
// HkdfExtract generates a pseudorandom key for use with Expand from an input secret and an optional independent salt.
|
||||
func HkdfExtract(hash crypto.Hash, secret, salt []byte) []byte {
|
||||
return hkdfExtract(hash, secret, salt)
|
||||
}
|
||||
|
||||
func hkdfExtract(hash crypto.Hash, secret, salt []byte) []byte {
|
||||
if salt == nil {
|
||||
salt = make([]byte, hash.Size())
|
||||
}
|
||||
|
||||
6
vendor/vendor.json
vendored
6
vendor/vendor.json
vendored
@@ -45,10 +45,10 @@
|
||||
"revisionTime": "2018-11-11T22:04:28Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "dpjM/eonkDPExO4QWg4+R0wZPCs=",
|
||||
"checksumSHA1": "9D0GoLWn+P00plU66qfLxFB1kNg=",
|
||||
"path": "github.com/marten-seemann/qtls",
|
||||
"revision": "26b223ad36d4436ed3eeb843041b66ac21dcee34",
|
||||
"revisionTime": "2019-01-06T03:45:47Z"
|
||||
"revision": "646330209b76bfdcdc054a863468f473e9d0a7af",
|
||||
"revisionTime": "2019-01-10T16:28:36Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "9TPZ7plxFmlYtMEv2LLXRCEQg7c=",
|
||||
|
||||
Reference in New Issue
Block a user