3
0
mirror of https://github.com/ergochat/ergo.git synced 2024-12-05 02:19:25 +01:00
ergo/irc/cloaks/cloaks.go

81 lines
1.9 KiB
Go
Raw Normal View History

2019-05-12 10:01:47 +02:00
// Copyright (c) 2019 Shivaram Lingamneni
package cloaks
import (
"fmt"
"net"
"golang.org/x/crypto/sha3"
"github.com/oragono/oragono/irc/utils"
)
type CloakConfig struct {
2020-05-08 07:16:49 +02:00
Enabled bool
Netname string
CidrLenIPv4 int `yaml:"cidr-len-ipv4"`
CidrLenIPv6 int `yaml:"cidr-len-ipv6"`
NumBits int `yaml:"num-bits"`
LegacySecretValue string `yaml:"secret"`
2019-05-12 10:01:47 +02:00
2020-05-08 07:16:49 +02:00
secret string
2019-05-12 10:01:47 +02:00
numBytes int
ipv4Mask net.IPMask
ipv6Mask net.IPMask
}
func (cloakConfig *CloakConfig) Initialize() {
2020-05-08 07:16:49 +02:00
if !cloakConfig.Enabled {
return
2020-01-09 19:49:36 +01:00
}
2019-05-12 10:01:47 +02:00
// sanity checks:
numBits := cloakConfig.NumBits
if 0 == numBits {
numBits = 80
} else if 256 < numBits {
numBits = 256
}
// derived values:
cloakConfig.numBytes = numBits / 8
// round up to the nearest byte
if numBits%8 != 0 {
cloakConfig.numBytes += 1
}
cloakConfig.ipv4Mask = net.CIDRMask(cloakConfig.CidrLenIPv4, 32)
cloakConfig.ipv6Mask = net.CIDRMask(cloakConfig.CidrLenIPv6, 128)
}
2020-05-08 07:16:49 +02:00
func (cloakConfig *CloakConfig) SetSecret(secret string) {
cloakConfig.secret = secret
}
2019-05-12 10:01:47 +02:00
// simple cloaking algorithm: normalize the IP to its CIDR,
// then hash the resulting bytes with a secret key,
// then truncate to the desired length, b32encode, and append the fake TLD.
func (config *CloakConfig) ComputeCloak(ip net.IP) string {
if !config.Enabled {
return ""
2020-05-08 07:16:49 +02:00
} else if config.NumBits == 0 || config.secret == "" {
2019-05-12 10:01:47 +02:00
return config.Netname
}
2020-05-08 07:16:49 +02:00
2019-05-12 10:01:47 +02:00
var masked net.IP
v4ip := ip.To4()
if v4ip != nil {
masked = v4ip.Mask(config.ipv4Mask)
} else {
masked = ip.Mask(config.ipv6Mask)
}
// SHA3(K || M):
// https://crypto.stackexchange.com/questions/17735/is-hmac-needed-for-a-sha-3-based-mac
2020-05-08 07:16:49 +02:00
input := make([]byte, len(config.secret)+len(masked))
copy(input, config.secret[:])
copy(input[len(config.secret):], masked)
2019-05-12 10:01:47 +02:00
digest := sha3.Sum512(input)
b32digest := utils.B32Encoder.EncodeToString(digest[:config.numBytes])
return fmt.Sprintf("%s.%s", b32digest, config.Netname)
}