diff options
Diffstat (limited to 'inform/codec.go')
-rw-r--r-- | inform/codec.go | 83 |
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 @@ | |||
1 | package inform | ||
2 | |||
3 | import ( | ||
4 | "bytes" | ||
5 | "encoding/binary" | ||
6 | "errors" | ||
7 | "io" | ||
8 | ) | ||
9 | |||
10 | type Codec struct { | ||
11 | // KeyBag contains a mapping of comma-separated MAC addresses to their AES | ||
12 | // keys | ||
13 | KeyBag map[string]string | ||
14 | } | ||
15 | |||
16 | func (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 | |||
55 | func (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 | } | ||