wacky encryption

This commit is contained in:
2026-07-22 13:53:30 +02:00
parent c09c5c4fd0
commit c9c4cc0af1
6 changed files with 204 additions and 67 deletions

View File

@@ -2,11 +2,13 @@
// TODO: authentication
// TODO: somehow persist IPs
// TODO: handle multiple peers behind one NAT
// TODO: key rotation
// TODO: sha256 -> HKDF
// TODO: recovery
package main
import (
"crypto/rand"
"encoding/base64"
"encoding/binary"
"log"
"net"
@@ -19,16 +21,13 @@ import (
type Peer struct {
RealAddr *net.UDPAddr
InternalIP string
PublicKey []byte
}
// 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() {
@@ -36,12 +35,6 @@ func main() {
panic("root permissions needed")
}
var err error
pskKey, err = base64.StdEncoding.DecodeString(PSK)
if err != nil {
panic(err)
}
receivePackets()
}
@@ -91,6 +84,8 @@ func handleReq(req []byte, addr *net.UDPAddr) {
peersMutex.Lock()
defer peersMutex.Unlock()
pubKey := req[4:]
internalIP := randomIP().String()
if destPeer, ok := peers[addr.IP.String()]; ok {
@@ -99,12 +94,13 @@ func handleReq(req []byte, addr *net.UDPAddr) {
peers[addr.IP.String()] = &Peer{
RealAddr: addr,
InternalIP: internalIP,
PublicKey: pubKey,
}
}
resp := shared.BuildPkt(shared.RESP_REGISTER, net.ParseIP(internalIP))
sendTo(addr, resp)
case shared.REQ_DATA:
case shared.ENC_PKT:
peersMutex.Lock()
peer := peers[addr.IP.String()]
peersMutex.Unlock()
@@ -113,38 +109,55 @@ func handleReq(req []byte, addr *net.UDPAddr) {
return
}
pkt, err := shared.DecryptSym(pskKey, req[4:])
if err != nil {
log.Printf("failed to decrypt packet from %s: %s", peer.RealAddr, err)
destIP := net.IP(req[4:20]).String()
srcIP := net.IP(req[20:36]).String()
if srcIP != peer.InternalIP {
log.Println("rejected spoofed srcIP in ENC_PKT")
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()
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 + " (*)")
broadcast(resp, peer.InternalIP)
} else if destPeer := getPeerByInternalIP(destIP); destPeer != nil {
log.Println(peer.InternalIP + " -> " + destIP)
sendTo(destPeer.RealAddr, resp)
} else {
log.Println(peer.InternalIP + " -/> " + destIP + " (unrecognized IP)")
}
default:
log.Printf("unhandled EtherType: 0x%x\n", etherType)
if destPeer := getPeerByInternalIP(destIP); destPeer != nil {
log.Println(srcIP + " -> " + destIP)
sendTo(destPeer.RealAddr, req)
} else {
log.Println(srcIP + " -/> " + destIP + " (unrecognized IP)")
}
case shared.BROADCAST_PKT:
peersMutex.Lock()
peer := peers[addr.IP.String()]
peersMutex.Unlock()
if peer == nil {
log.Println("data from unregistered peer:", addr.String())
return
}
destIP := net.IP(req[42:58]).String()
log.Println(peer.InternalIP + " -> " + destIP)
broadcast(req, peer.InternalIP)
case shared.REQ_GET_PUBKEY:
peerIP := net.IP(req[4:20]).String()
peer := getPeerByInternalIP(peerIP)
if peer == nil {
log.Println(addr.String(), "tried to get pubkey of unknown peer", peerIP)
return
}
resp := shared.BuildPkt(shared.RESP_GET_PUBKEY, append(net.ParseIP(peer.InternalIP), peer.PublicKey...))
sendTo(addr, resp)
case shared.REQ_ESTABLISH, shared.RESP_ESTABLISH:
peersMutex.Lock()
peer := peers[addr.IP.String()]
peersMutex.Unlock()
srcIP := net.IP(req[20:36]).String()
if srcIP != peer.InternalIP {
log.Println("rejected spoofed srcIP in ESTABLISH")
return
}
dstIP := net.IP(req[4:20]).String()
dstPeer := getPeerByInternalIP(dstIP)
sendTo(dstPeer.RealAddr, req)
default:
log.Println("unknown packet type")
}