encrypt traffic with pre-shared key

This commit is contained in:
2026-07-22 11:05:00 +02:00
parent e58731bd34
commit c09c5c4fd0
6 changed files with 110 additions and 26 deletions

View File

@@ -1,12 +1,12 @@
// TODO: slice bounds checking
// TODO: authentication
// TODO: encryption
// TODO: somehow persist IPs
// TODO: handle multiple peers behind one NAT
package main
import (
"crypto/rand"
"encoding/base64"
"encoding/binary"
"log"
"net"
@@ -21,10 +21,14 @@ type Peer struct {
InternalIP string
}
// TODO: replace with key exchange between peers
const PSK = "rj5FvWB0n342C6UGrAS0gI3GX5ya+lDmC7/XmgFHF+s="
var (
peers = map[string]*Peer{}
peersMutex sync.Mutex
conn *net.UDPConn
pskKey []byte
)
func main() {
@@ -32,6 +36,12 @@ func main() {
panic("root permissions needed")
}
var err error
pskKey, err = base64.StdEncoding.DecodeString(PSK)
if err != nil {
panic(err)
}
receivePackets()
}
@@ -59,25 +69,22 @@ func receivePackets() {
continue
}
go receivePacket(buffer[:n], addr)
go handleReq(buffer[:n], addr)
}
}
func receivePacket(pkt []byte, addr *net.UDPAddr) {
if len(pkt) < 4 {
func handleReq(req []byte, addr *net.UDPAddr) {
if len(req) < 4 {
log.Println("packet too short")
return
}
version := binary.LittleEndian.Uint16(pkt[0:])
version := binary.LittleEndian.Uint16(req[0:])
if version != shared.PROTO_VERSION {
log.Println("mismatched packet version")
return
}
pktType := binary.LittleEndian.Uint16(pkt[2:])
// idk if it needs to lock the mutex
peer := peers[addr.IP.String()]
pktType := binary.LittleEndian.Uint16(req[2:])
switch pktType {
case shared.REQ_REGISTER:
@@ -98,15 +105,33 @@ func receivePacket(pkt []byte, addr *net.UDPAddr) {
resp := shared.BuildPkt(shared.RESP_REGISTER, net.ParseIP(internalIP))
sendTo(addr, resp)
case shared.REQ_DATA:
frame := pkt[4:]
etherType := binary.BigEndian.Uint16(frame[12:14])
payload := frame[14:]
peersMutex.Lock()
peer := peers[addr.IP.String()]
peersMutex.Unlock()
if peer == nil {
log.Println("data from unregistered peer:", addr.String())
return
}
pkt, err := shared.DecryptSym(pskKey, req[4:])
if err != nil {
log.Printf("failed to decrypt packet from %s: %s", peer.RealAddr, err)
return
}
etherType := binary.BigEndian.Uint16(pkt[12:14])
payload := pkt[14:]
switch etherType {
case 0x86dd: // IPv6
rawDestIP := payload[24:40]
destIP := net.IP(rawDestIP).String()
resp := shared.BuildPkt(shared.RESP_DATA, frame)
encryptedPkt, err := shared.EncryptSym(pskKey, pkt)
if err != nil {
panic(err)
}
resp := shared.BuildPkt(shared.RESP_DATA, encryptedPkt)
if rawDestIP[0] == 0xff { // multicast
log.Println(peer.InternalIP + " -> " + destIP + " (*)")