1 package transport
2 3 import (
4 "crypto/cipher"
5 "crypto/rand"
6 "encoding/hex"
7 "errors"
8 "fmt"
9 "io"
10 )
11 12 // DecryptMessage attempts to decode the received message
13 func DecryptMessage(creator string, ciph cipher.AEAD, data []byte) (msg []byte, e error) {
14 nonceSize := ciph.NonceSize()
15 msg, e = ciph.Open(nil, data[:nonceSize], data[nonceSize:], nil)
16 if e != nil {
17 e = errors.New(fmt.Sprintf("%s %s", creator, e.Error()))
18 } else {
19 D.Ln("decrypted message", hex.EncodeToString(data[:nonceSize]))
20 }
21 return
22 }
23 24 // EncryptMessage encrypts a message, if the nonce is given it uses that
25 // otherwise it generates a new one. If there is no cipher this just returns a
26 // message with the given magic prepended.
27 func EncryptMessage(creator string, ciph cipher.AEAD, magic []byte, nonce, data []byte) (msg []byte, e error) {
28 if ciph != nil {
29 if nonce == nil {
30 nonce, e = GetNonce(ciph)
31 }
32 msg = append(append(magic, nonce...), ciph.Seal(nil, nonce, data, nil)...)
33 } else {
34 msg = append(magic, data...)
35 }
36 return
37 }
38 39 // GetNonce reads from a cryptographicallly secure random number source
40 func GetNonce(ciph cipher.AEAD) (nonce []byte, e error) {
41 // get a nonce for the packet, it is both message ID and salt
42 nonce = make([]byte, ciph.NonceSize())
43 if _, e = io.ReadFull(rand.Reader, nonce); E.Chk(e) {
44 }
45 return
46 }
47