mirror of
https://github.com/sot-tech/mochi.git
synced 2026-05-13 06:48:37 -07:00
udp: Rotate connection ID generation IVs every hour
This commit is contained in:
@@ -5,31 +5,37 @@
|
||||
package udp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
)
|
||||
|
||||
var connectionKey, connectionIV []byte
|
||||
type ConnectionIDGenerator struct {
|
||||
iv, iv2 []byte
|
||||
block cipher.Block
|
||||
}
|
||||
|
||||
func InitConnectionIDEncryption() error {
|
||||
connectionKey = make([]byte, 16)
|
||||
_, err := rand.Read(connectionKey)
|
||||
func (g *ConnectionIDGenerator) Init() error {
|
||||
key := make([]byte, 16)
|
||||
_, err := rand.Read(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
connectionIV = make([]byte, 16)
|
||||
_, err = rand.Read(connectionIV)
|
||||
return err
|
||||
}
|
||||
|
||||
func GenerateConnectionID(ip []byte) []byte {
|
||||
block, err := aes.NewCipher(connectionKey)
|
||||
g.block, err = aes.NewCipher(key)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return err
|
||||
}
|
||||
|
||||
return g.NewIV()
|
||||
}
|
||||
|
||||
func (g *ConnectionIDGenerator) Generate(ip []byte) []byte {
|
||||
return g.generate(ip, g.iv)
|
||||
}
|
||||
|
||||
func (g *ConnectionIDGenerator) generate(ip []byte, iv []byte) []byte {
|
||||
if len(ip) > 16 {
|
||||
panic("IP larger than 16 bytes")
|
||||
}
|
||||
@@ -39,7 +45,7 @@ func GenerateConnectionID(ip []byte) []byte {
|
||||
}
|
||||
|
||||
ct := make([]byte, 16)
|
||||
stream := cipher.NewCFBDecrypter(block, connectionIV)
|
||||
stream := cipher.NewCFBDecrypter(g.block, iv)
|
||||
stream.XORKeyStream(ct, ip)
|
||||
|
||||
for i := len(ip) - 1; i >= 8; i-- {
|
||||
@@ -49,6 +55,28 @@ func GenerateConnectionID(ip []byte) []byte {
|
||||
return ct[:8]
|
||||
}
|
||||
|
||||
func init() {
|
||||
InitConnectionIDEncryption()
|
||||
func (g *ConnectionIDGenerator) Matches(id []byte, ip []byte) bool {
|
||||
if expected := g.generate(ip, g.iv); bytes.Equal(id, expected) {
|
||||
return true
|
||||
}
|
||||
|
||||
if iv2 := g.iv2; iv2 != nil {
|
||||
if expected := g.generate(ip, iv2); bytes.Equal(id, expected) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (g *ConnectionIDGenerator) NewIV() error {
|
||||
newiv := make([]byte, 16)
|
||||
if _, err := rand.Read(newiv); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
g.iv2 = g.iv
|
||||
g.iv = newiv
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user