Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

cloaks.go 1.9KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. // Copyright (c) 2019 Shivaram Lingamneni
  2. package cloaks
  3. import (
  4. "fmt"
  5. "net"
  6. "golang.org/x/crypto/sha3"
  7. "github.com/oragono/oragono/irc/utils"
  8. )
  9. type CloakConfig struct {
  10. Enabled bool
  11. Netname string
  12. CidrLenIPv4 int `yaml:"cidr-len-ipv4"`
  13. CidrLenIPv6 int `yaml:"cidr-len-ipv6"`
  14. NumBits int `yaml:"num-bits"`
  15. LegacySecretValue string `yaml:"secret"`
  16. secret string
  17. numBytes int
  18. ipv4Mask net.IPMask
  19. ipv6Mask net.IPMask
  20. }
  21. func (cloakConfig *CloakConfig) Initialize() {
  22. if !cloakConfig.Enabled {
  23. return
  24. }
  25. // sanity checks:
  26. numBits := cloakConfig.NumBits
  27. if 0 == numBits {
  28. numBits = 80
  29. } else if 256 < numBits {
  30. numBits = 256
  31. }
  32. // derived values:
  33. cloakConfig.numBytes = numBits / 8
  34. // round up to the nearest byte
  35. if numBits%8 != 0 {
  36. cloakConfig.numBytes += 1
  37. }
  38. cloakConfig.ipv4Mask = net.CIDRMask(cloakConfig.CidrLenIPv4, 32)
  39. cloakConfig.ipv6Mask = net.CIDRMask(cloakConfig.CidrLenIPv6, 128)
  40. }
  41. func (cloakConfig *CloakConfig) SetSecret(secret string) {
  42. cloakConfig.secret = secret
  43. }
  44. // simple cloaking algorithm: normalize the IP to its CIDR,
  45. // then hash the resulting bytes with a secret key,
  46. // then truncate to the desired length, b32encode, and append the fake TLD.
  47. func (config *CloakConfig) ComputeCloak(ip net.IP) string {
  48. if !config.Enabled {
  49. return ""
  50. } else if config.NumBits == 0 || config.secret == "" {
  51. return config.Netname
  52. }
  53. var masked net.IP
  54. v4ip := ip.To4()
  55. if v4ip != nil {
  56. masked = v4ip.Mask(config.ipv4Mask)
  57. } else {
  58. masked = ip.Mask(config.ipv6Mask)
  59. }
  60. // SHA3(K || M):
  61. // https://crypto.stackexchange.com/questions/17735/is-hmac-needed-for-a-sha-3-based-mac
  62. input := make([]byte, len(config.secret)+len(masked))
  63. copy(input, config.secret[:])
  64. copy(input[len(config.secret):], masked)
  65. digest := sha3.Sum512(input)
  66. b32digest := utils.B32Encoder.EncodeToString(digest[:config.numBytes])
  67. return fmt.Sprintf("%s.%s", b32digest, config.Netname)
  68. }