aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpg9182 <96569817+pg9182@users.noreply.github.com>2023-03-08 19:48:51 -0500
committerpg9182 <96569817+pg9182@users.noreply.github.com>2023-04-17 14:49:47 -0400
commit5cdaae7128d59b5afc0126621273075465d8afe3 (patch)
tree6c550b53f5e97c01b673d91c173941667a6212d1
parentf6d85eaf1c969bfc10d70d57c43328588d69fde1 (diff)
downloadAtlas-5cdaae7128d59b5afc0126621273075465d8afe3.tar.gz
Atlas-5cdaae7128d59b5afc0126621273075465d8afe3.zip
pkg/a2s: Remove unused package
-rw-r--r--pkg/a2s/a2s.go201
-rw-r--r--pkg/a2s/a2s_test.go107
2 files changed, 0 insertions, 308 deletions
diff --git a/pkg/a2s/a2s.go b/pkg/a2s/a2s.go
deleted file mode 100644
index 11cfc7c..0000000
--- a/pkg/a2s/a2s.go
+++ /dev/null
@@ -1,201 +0,0 @@
-// Package a2s implements a small portion of the r2 netchannel used by Northstar
-// to probe servers.
-package a2s
-
-import (
- "bytes"
- "crypto/aes"
- "crypto/cipher"
- "crypto/hmac"
- "crypto/rand"
- "crypto/sha256"
- "encoding/binary"
- "encoding/json"
- "errors"
- "fmt"
- "net"
- "net/netip"
- "os"
- "time"
-)
-
-const ProbeUID uint64 = 1000000001337
-
-var ErrTimeout = errors.New("connection timed out")
-
-func Probe(addr netip.AddrPort, timeout time.Duration) error {
- conn, err := net.DialUDP("udp", nil, net.UDPAddrFromAddrPort(addr))
- if err != nil {
- return fmt.Errorf("connect to server: %w", err)
- }
- defer conn.Close()
-
- t := time.Now().Add(timeout)
- conn.SetWriteDeadline(t)
- conn.SetReadDeadline(t)
-
- pkt, err := r2cryptoEncrypt(r2encodeGetChallenge(ProbeUID))
- if err != nil {
- return fmt.Errorf("encrypt connection packet: %w", err)
- }
- if _, err := conn.Write(pkt); err != nil {
- if errors.Is(err, os.ErrDeadlineExceeded) {
- err = fmt.Errorf("%w: %v", ErrTimeout, err)
- }
- return fmt.Errorf("send connection packet: %w", err)
- }
-
- resp := make([]byte, 1500)
- if n, err := conn.Read(resp); err != nil {
- if errors.Is(err, os.ErrDeadlineExceeded) {
- err = fmt.Errorf("%w: %v", ErrTimeout, err)
- }
- return fmt.Errorf("receive packet: %w", err)
- } else {
- resp = resp[:n]
- }
-
- dec, err := r2cryptoDecrypt(resp)
- if err != nil {
- return fmt.Errorf("failed to decrypt received packet: %w", err)
- }
-
- uid, _, err := r2decodeChallenge(dec)
- if err != nil {
- return fmt.Errorf("invalid challenge: %w", err)
- }
- if uid != ProbeUID {
- return fmt.Errorf("invalid challenge")
- }
- return nil
-}
-
-func AtlasSigreq1(addr netip.AddrPort, timeout time.Duration, key string, obj any) error {
- // TODO: unconnected udp for performance
-
- a := net.UDPAddrFromAddrPort(addr)
- conn, err := net.DialUDP("udp", nil, a)
- if err != nil {
- return err
- }
- defer conn.Close()
-
- t := time.Now().Add(timeout)
- conn.SetWriteDeadline(t)
-
- j, err := json.Marshal(obj)
- if err != nil {
- return err
- }
-
- pkt, err := r2cryptoEncrypt(r2encodeAtlasSigreq1([]byte(key), j))
- if err != nil {
- return fmt.Errorf("encrypt packet: %w", err)
- }
- if _, err := conn.Write(pkt); err != nil {
- if errors.Is(err, os.ErrDeadlineExceeded) {
- err = fmt.Errorf("%w: %v", ErrTimeout, err)
- }
- return fmt.Errorf("send packet: %w", err)
- }
- return nil
-}
-
-const (
- r2cryptoNonceSize = 12
- r2cryptoTagSize = 16
- r2cryptoKey = "X3V.bXCfe3EhN'wb"
- r2cryptoAAD = "\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10"
-)
-
-func r2cryptoEncrypt(b []byte) ([]byte, error) {
- pkt := make([]byte, r2cryptoNonceSize+r2cryptoTagSize+len(b))
-
- nonce := pkt[:r2cryptoNonceSize]
- if _, err := rand.Read(nonce); err != nil {
- return nil, err
- }
-
- c, err := aes.NewCipher([]byte(r2cryptoKey))
- if err != nil {
- panic(err)
- }
-
- a, err := cipher.NewGCMWithTagSize(c, r2cryptoTagSize)
- if err != nil {
- panic(err)
- }
-
- // Go appends the ciphertext, then the tag to the dest (nonce)
- tmp := a.Seal(nil, nonce, b, []byte(r2cryptoAAD))
- copy(pkt[r2cryptoNonceSize:], tmp[len(b):])
- copy(pkt[r2cryptoNonceSize+r2cryptoTagSize:], tmp)
- return pkt, nil
-}
-
-func r2cryptoDecrypt(b []byte) ([]byte, error) {
- if len(b) < r2cryptoNonceSize+r2cryptoTagSize+1 {
- return nil, fmt.Errorf("packet too small")
- }
-
- c, err := aes.NewCipher([]byte(r2cryptoKey))
- if err != nil {
- panic(err)
- }
-
- a, err := cipher.NewGCMWithTagSize(c, r2cryptoTagSize)
- if err != nil {
- panic(err)
- }
-
- tmp := make([]byte, len(b)-r2cryptoNonceSize)
- copy(tmp, b[r2cryptoNonceSize+r2cryptoTagSize:])
- copy(tmp[len(tmp)-r2cryptoTagSize:], b[r2cryptoNonceSize:])
-
- if tmp, err = a.Open(tmp[:0], b[:r2cryptoNonceSize], tmp, []byte(r2cryptoAAD)); err != nil {
- return nil, err
- }
- return tmp, nil
-}
-
-func r2encodeGetChallenge(uid uint64) []byte {
- var b bytes.Buffer
- binary.Write(&b, binary.LittleEndian, int32(-1))
- binary.Write(&b, binary.LittleEndian, uint8(72))
- binary.Write(&b, binary.LittleEndian, []byte("connect\x00"))
- binary.Write(&b, binary.LittleEndian, uint64(uid))
- binary.Write(&b, binary.LittleEndian, uint8(2))
- return b.Bytes()
-}
-
-func r2encodeAtlasSigreq1(key, data []byte) []byte {
- sig := hmac.New(sha256.New, key)
- sig.Write(data)
-
- var b []byte
- b = append(b, '\xFF', '\xFF', '\xFF', '\xFF') // connectionless: int32(-1)
- b = append(b, 'T') // packet kind
- b = append(b, "sigreq1\x00"...) // packet type
- b = sig.Sum(b) // sigreq1 - signature
- b = append(b, data...) // sigreq1 - data
- return b
-}
-
-func r2decodeChallenge(b []byte) (uint64, int32, error) {
- var pkt struct {
- Seq int32
- Type uint8
- Challenge int32
- UID uint64
- }
- if err := binary.Read(bytes.NewReader(b), binary.LittleEndian, &pkt); err != nil {
- return 0, 0, err
- }
- if pkt.Seq != -1 {
- return 0, 0, fmt.Errorf("not a connectionless packet")
- }
- if pkt.Type != 73 {
- return 0, 0, fmt.Errorf("not a challenge response")
- }
- return pkt.UID, pkt.Challenge, nil
-}
diff --git a/pkg/a2s/a2s_test.go b/pkg/a2s/a2s_test.go
deleted file mode 100644
index b97b5c4..0000000
--- a/pkg/a2s/a2s_test.go
+++ /dev/null
@@ -1,107 +0,0 @@
-package a2s
-
-import (
- "bytes"
- "encoding/hex"
- "fmt"
- "testing"
-)
-
-func TestPacketRoundTrip(t *testing.T) {
- b := r2encodeGetChallenge(1000000001337)
- e := mustDecodeHex("ffffffff48636f6e6e656374003915a5d4e800000002")
-
- if !bytes.Equal(b, e) {
- t.Error("incorrect getchallenge encoding")
- }
-
- be, err := r2cryptoEncrypt(b)
- if err != nil {
- t.Errorf("failed to encrypt packet: %v", err)
- }
-
- bd, err := r2cryptoDecrypt(be)
- if err != nil {
- t.Errorf("failed to decrypt packet: %v", err)
- }
-
- if !bytes.Equal(bd, b) {
- t.Error("incorrect decryption result")
- }
-}
-
-func TestDecodeChallenge(t *testing.T) {
- b := mustDecodeHex("f4ca55b7f53a2f9c19b563010d6964869648a23be1db9edce9f55ee3f9a02451be86ba56447740d1d893c34f3a854f6efbd47605ebf3211e05")
-
- bd, err := r2cryptoDecrypt(b)
- if err != nil {
- t.Errorf("failed to decrypt packet: %v", err)
- }
-
- uid, challenge, err := r2decodeChallenge(bd)
- if err != nil {
- t.Errorf("failed to parse packet: %v", err)
- }
-
- if uid != 1000000001337 {
- t.Errorf("incorrect uid")
- }
-
- if challenge != 81930672 {
- t.Errorf("incorrect challenge")
- }
-}
-
-func TestAtlasSigreq1(t *testing.T) {
- b := mustDecodeHex("ffffffff547369677265713100803dab964c7c71851c05de40f5bf4cf72743951c96f2f0b81139ca780203260674657374")
- a := r2encodeAtlasSigreq1([]byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), []byte("test"))
- if !bytes.Equal(a, b) {
- t.Errorf("incorrect encoding: expected %x, got %x", b, a)
- }
-}
-
-func FuzzGetChallenge(f *testing.F) {
- f.Add(uint64(0))
- f.Add(uint64(1000000001337))
-
- f.Fuzz(func(t *testing.T, uid uint64) {
- b := r2encodeGetChallenge(uid)
-
- be, err := r2cryptoEncrypt(b)
- if err != nil {
- t.Errorf("failed to encrypt packet: %v", err)
- }
-
- bd, err := r2cryptoDecrypt(be)
- if err != nil {
- t.Errorf("failed to decrypt packet: %v", err)
- }
-
- if !bytes.Equal(bd, b) {
- t.Error("incorrect decryption result")
- }
- })
-}
-
-func FuzzChallenge(f *testing.F) {
- f.Add(mustDecodeHex("aa"))
- f.Add(mustDecodeHex("aaaaaaaaaaaaaa"))
- f.Add(mustDecodeHex("00000000000000"))
- f.Add(mustDecodeHex("09f7b6c1f41d91ecb41f370e9fd085610e5ee98827ba7aa9789557e18ddb2a28587f635a008aa71b9cb7b3f38b3ccd8d1ff0"))
- f.Add(mustDecodeHex("edf3552e5d364fb3ab5505822c45c107208251b836022ad94698d920cfec348c469a861d14b5af2d8ca12702d09a7d91796e"))
- f.Add(mustDecodeHex("f4ca55b7f53a2f9c19b563010d6964869648a23be1db9edce9f55ee3f9a02451be86ba56447740d1d893c34f3a854f6efbd47605ebf3211e05"))
- f.Add(mustDecodeHex("bb8aaeed936b6dea21ba8bf4db5ca22a823a122307d5c6bc4124994581eb07b7996575acbbafe28ea4aee8bb58c681e33528470900007b012a"))
-
- f.Fuzz(func(_ *testing.T, pkt []byte) {
- // ensure this doesn't panic
- r2cryptoDecrypt(pkt)
- })
-}
-
-func mustDecodeHex(s string) []byte {
- b, err := hex.DecodeString(s)
- if err != nil {
- panic(fmt.Errorf("decode %q: %w", s, err))
- }
- return b
-}