1package mox
2
3import (
4 "context"
5 cryptorand "crypto/rand"
6 "crypto/tls"
7 "time"
8
9 "github.com/mjl-/mox/mlog"
10)
11
12// StartTLSSessionTicketKeyRefresher sets session keys on the TLS config, and
13// rotates them periodically.
14//
15// Useful for TLS configs that are being cloned for each connection. The
16// automatically managed keys would happen in the cloned config, and not make
17// it back to the base config.
18func StartTLSSessionTicketKeyRefresher(ctx context.Context, log mlog.Log, c *tls.Config) {
19 var keys [][32]byte
20 first := make(chan struct{})
21
22 // Similar to crypto/tls, we rotate keys once a day. Previous keys stay valid for 7
23 // days. We currently only store ticket keys in memory, so a restart invalidates
24 // previous session tickets. We could store them in the future.
25 go func() {
26 for {
27 var nk [32]byte
28 cryptorand.Read(nk[:])
29 if len(keys) > 7 {
30 keys = keys[:7]
31 }
32 keys = append([][32]byte{nk}, keys...)
33 c.SetSessionTicketKeys(keys)
34
35 if first != nil {
36 first <- struct{}{}
37 first = nil
38 }
39
40 ctxDone := Sleep(ctx, 24*time.Hour)
41 if ctxDone {
42 break
43 }
44 log.Info("rotating tls session keys")
45 }
46 }()
47
48 <-first
49}
50