aboutsummaryrefslogtreecommitdiff
path: root/inform/codec.go
diff options
context:
space:
mode:
Diffstat (limited to 'inform/codec.go')
-rw-r--r--inform/codec.go83
1 files changed, 83 insertions, 0 deletions
diff --git a/inform/codec.go b/inform/codec.go
new file mode 100644
index 0000000..e74c3d7
--- /dev/null
+++ b/inform/codec.go
@@ -0,0 +1,83 @@
1package inform
2
3import (
4 "bytes"
5 "encoding/binary"
6 "errors"
7 "io"
8)
9
10type Codec struct {
11 // KeyBag contains a mapping of comma-separated MAC addresses to their AES
12 // keys
13 KeyBag map[string]string
14}
15
16func (c *Codec) Unmarshal(fp io.Reader) (*InformWrapper, error) {
17 w := NewInformWrapper()
18
19 var magic int32
20 binary.Read(fp, binary.BigEndian, &magic)
21 if magic != PROTOCOL_MAGIC {
22 return nil, errors.New("Invalid magic number")
23 }
24
25 binary.Read(fp, binary.BigEndian, &w.Version)
26 io.ReadFull(fp, w.MacAddr)
27 binary.Read(fp, binary.BigEndian, &w.Flags)
28
29 iv := make([]byte, 16)
30 io.ReadFull(fp, iv)
31
32 binary.Read(fp, binary.BigEndian, &w.DataVersion)
33
34 var dataLen int32
35 binary.Read(fp, binary.BigEndian, &dataLen)
36
37 p := make([]byte, dataLen)
38 io.ReadFull(fp, p)
39
40 key, ok := c.KeyBag[w.FormattedMac()]
41 if !ok {
42 return nil, errors.New("No key found")
43 }
44
45 u, err := Decrypt(p, iv, key)
46 if err != nil {
47 return nil, err
48 }
49
50 w.Payload = u
51
52 return w, nil
53}
54
55func (c *Codec) Marshal(msg *InformWrapper) ([]byte, error) {
56 b := &bytes.Buffer{}
57 payload := msg.Payload
58 var iv []byte
59
60 if msg.IsEncrypted() {
61 key, ok := c.KeyBag[msg.FormattedMac()]
62 if !ok {
63 return nil, errors.New("No key found")
64 }
65
66 var err error
67 payload, iv, err = Encrypt(payload, key)
68 if err != nil {
69 return nil, err
70 }
71 }
72
73 binary.Write(b, binary.BigEndian, PROTOCOL_MAGIC)
74 binary.Write(b, binary.BigEndian, msg.Version)
75 b.Write(msg.MacAddr)
76 binary.Write(b, binary.BigEndian, msg.Flags)
77 b.Write(iv)
78 binary.Write(b, binary.BigEndian, msg.DataVersion)
79 binary.Write(b, binary.BigEndian, int32(len(payload)))
80 b.Write(payload)
81
82 return b.Bytes(), nil
83}