route/vendor/github.com/lucas-clemente/quic-go/internal/handshake/ephermal_cache.go

51 lines
1.4 KiB
Go
Raw Normal View History

2017-12-12 02:51:45 +00:00
package handshake
import (
"sync"
"time"
2018-01-03 19:19:49 +00:00
"github.com/lucas-clemente/quic-go/internal/crypto"
"github.com/lucas-clemente/quic-go/internal/protocol"
"github.com/lucas-clemente/quic-go/internal/utils"
2017-12-12 02:51:45 +00:00
)
var (
kexLifetime = protocol.EphermalKeyLifetime
kexCurrent crypto.KeyExchange
kexCurrentTime time.Time
kexMutex sync.RWMutex
)
// getEphermalKEX returns the currently active KEX, which changes every protocol.EphermalKeyLifetime
// See the explanation from the QUIC crypto doc:
//
// A single connection is the usual scope for forward security, but the security
// difference between an ephemeral key used for a single connection, and one
// used for all connections for 60 seconds is negligible. Thus we can amortise
// the Diffie-Hellman key generation at the server over all the connections in a
// small time span.
func getEphermalKEX() (res crypto.KeyExchange) {
kexMutex.RLock()
res = kexCurrent
t := kexCurrentTime
kexMutex.RUnlock()
2018-01-03 19:19:49 +00:00
if res != nil && time.Since(t) < kexLifetime {
2017-12-12 02:51:45 +00:00
return res
}
kexMutex.Lock()
defer kexMutex.Unlock()
// Check if still unfulfilled
2018-01-03 19:19:49 +00:00
if kexCurrent == nil || time.Since(kexCurrentTime) > kexLifetime {
2017-12-12 02:51:45 +00:00
kex, err := crypto.NewCurve25519KEX()
if err != nil {
utils.Errorf("could not set KEX: %s", err.Error())
return kexCurrent
}
kexCurrent = kex
kexCurrentTime = time.Now()
return kexCurrent
}
return kexCurrent
}