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 if _, err := cryptorand.Read(nk[:]); err != nil {
29 panic(err)
30 }
31 if len(keys) > 7 {
32 keys = keys[:7]
33 }
34 keys = append([][32]byte{nk}, keys...)
35 c.SetSessionTicketKeys(keys)
36
37 if first != nil {
38 first <- struct{}{}
39 first = nil
40 }
41
42 ctxDone := Sleep(ctx, 24*time.Hour)
43 if ctxDone {
44 break
45 }
46 log.Info("rotating tls session keys")
47 }
48 }()
49
50 <-first
51}
52