Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package main
- /*
- * receiver.go
- * Receive data from the network, unpack/unencrypt it
- * By J. Stuart McMurray
- * Created 20160226
- * Last Modified 20160226
- */
- import (
- "fmt"
- "io"
- "net"
- "golang.org/x/crypto/nacl/secretbox"
- )
- const (
- IP4HLEN = 20 /* IPv4 Header Length */
- IP6HLEN = 40 /* IPv6 Header Length */
- )
- /* recv receives packets from in, decrypts them, and sends to out. If there
- is an error, it will be sent to ec. */
- func recv(out io.Writer, in *net.IPConn, key [KEYLEN]byte, ec chan<- error) {
- if err := xmit(out, in, key, unroll); nil != err {
- ec <- err
- }
- ec <- nil
- }
- /* unroll takes the packet in msg, chops off the IP header, decrypts the
- packet, puts the plaintext in buf, and returns buf. Non-fatal errors will
- cause a log message to be printed, but no error will be returned. */
- func unroll(buf, msg []byte, key [KEYLEN]byte) ([]byte, error) {
- buf = buf[0:0]
- /* Get the nonce and ciphertext */
- nonce, msg, err := splitPacket(msg)
- if nil != err {
- return buf, err
- }
- ok := false
- buf, ok = secretbox.Open(buf, msg, &nonce, &key)
- if !ok {
- return buf, fmt.Errorf("decrypt failed")
- }
- return buf, nil
- }
- /* splitPacket returns the nonce and payload from a packet. */
- func splitPacket(msg []byte) (
- nonce [NONCELEN]byte,
- payload []byte,
- err error,
- ) {
- /* Remove the header */
- msg, err = chopHeader(msg)
- if nil != err {
- return nonce, msg, err
- }
- /* If there's no bytes left, it's probably a heartbeet */
- if 0 == len(msg) {
- return nonce, msg, HeartBeetError
- }
- /* Pull off the nonce */
- if NONCELEN > len(msg) {
- return nonce, msg, fmt.Errorf(
- "packet body too small for nonce: %02X",
- msg,
- )
- }
- for i, _ := range nonce {
- nonce[i] = msg[i]
- }
- /* The rest is the payload */
- payload = msg[NONCELEN:]
- return nonce, payload, err
- }
- /* chopHeader reslices pkt to remove the IP header. */
- func chopHeader(pkt []byte) ([]byte, error) {
- /* Switch by IP version */
- switch (pkt[0] & 0xF0) >> 4 {
- case 4:
- if IP4HLEN > len(pkt) {
- return pkt, fmt.Errorf(
- "message too small (<%v bytes)",
- IP4HLEN,
- )
- }
- pkt = pkt[IP4HLEN:]
- case 6:
- if IP6HLEN > len(pkt) {
- return pkt, fmt.Errorf(
- "message too small (<%v bytes)",
- IP6HLEN,
- )
- }
- pkt = pkt[IP6HLEN:]
- default:
- return pkt, fmt.Errorf(
- "unknown IP version: %02X",
- pkt,
- )
- }
- return pkt, nil
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement