1
2
3
4
5 package quic
6
7 import (
8 "crypto/hmac"
9 "crypto/rand"
10 "crypto/sha256"
11 "hash"
12 "sync"
13 )
14
15 const statelessResetTokenLen = 128 / 8
16
17
18
19 type statelessResetToken [statelessResetTokenLen]byte
20
21 type statelessResetTokenGenerator struct {
22 canReset bool
23
24
25
26
27
28
29
30 mu sync.Mutex
31 mac hash.Hash
32 }
33
34 func (g *statelessResetTokenGenerator) init(secret [32]byte) {
35 zero := true
36 for _, b := range secret {
37 if b != 0 {
38 zero = false
39 break
40 }
41 }
42 if zero {
43
44 rand.Read(secret[:])
45 g.canReset = false
46 } else {
47 g.canReset = true
48 }
49 g.mac = hmac.New(sha256.New, secret[:])
50 }
51
52 func (g *statelessResetTokenGenerator) tokenForConnID(cid []byte) (token statelessResetToken) {
53 g.mu.Lock()
54 defer g.mu.Unlock()
55 defer g.mac.Reset()
56 g.mac.Write(cid)
57 copy(token[:], g.mac.Sum(nil))
58 return token
59 }
60
View as plain text