wacky encryption
This commit is contained in:
@@ -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")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user