mirror of
https://github.com/maride/afl-transmit.git
synced 2026-04-14 19:15:45 +00:00
Add AES encryption between nodes
This commit is contained in:
86
net/crypt.go
Normal file
86
net/crypt.go
Normal file
@@ -0,0 +1,86 @@
|
||||
package net
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
var (
|
||||
key string
|
||||
sharedGCM cipher.AEAD
|
||||
nonceSize int
|
||||
)
|
||||
|
||||
// RegisterCryptFlags Registers the flags required for cryptography
|
||||
func RegisterCryptFlags() {
|
||||
flag.StringVar(&key, "key", "", "32 random bytes, base64-wrapped, to AES-encrypt traffic between nodes")
|
||||
}
|
||||
|
||||
// InitCrypt creates a cipher object out of the key handed over via --key
|
||||
func InitCrypt() error {
|
||||
// Check if a key was handed over
|
||||
if key == "" {
|
||||
// no key, no service
|
||||
return nil
|
||||
}
|
||||
|
||||
// Unwrap base64'ed crypto bytes
|
||||
rawKey, base64Err := base64.StdEncoding.DecodeString(key)
|
||||
if base64Err != nil {
|
||||
return fmt.Errorf("failed to unpack base64'ed key: %s", base64Err)
|
||||
}
|
||||
|
||||
// Create cipher object using that key
|
||||
block, cipherErr := aes.NewCipher(rawKey)
|
||||
if cipherErr != nil {
|
||||
return fmt.Errorf("failed to use your key as AES256 key: %s", cipherErr)
|
||||
}
|
||||
|
||||
// Create GCM with cipher object
|
||||
gcm, gcmErr := cipher.NewGCM(block)
|
||||
if gcmErr != nil {
|
||||
return fmt.Errorf("failed to create GCM for your key: %s", gcmErr)
|
||||
}
|
||||
|
||||
// Set shared GCM instance
|
||||
sharedGCM = gcm
|
||||
nonceSize = gcm.NonceSize()
|
||||
|
||||
// No error to report
|
||||
return nil
|
||||
}
|
||||
|
||||
// CryptApplicable checks if we are able to encrypt or decrypt things, means if this instance was given a proper key
|
||||
func CryptApplicable() bool {
|
||||
// if the shared GCM object is set, we were able to get the key off user's hands, else we don't crypt
|
||||
return sharedGCM != nil
|
||||
}
|
||||
|
||||
// Encrypt encrypts the given bytes using the symmetric key
|
||||
func Encrypt(plain []byte) ([]byte, error) {
|
||||
// create nonce and fill it with random bytes
|
||||
nonce := make([]byte, nonceSize)
|
||||
_, readErr := io.ReadFull(rand.Reader, nonce)
|
||||
if readErr != nil {
|
||||
return nil, fmt.Errorf("failed to get random bytes: %s", readErr)
|
||||
}
|
||||
|
||||
// Encrypt plaintext
|
||||
return sharedGCM.Seal(nonce, nonce, plain, nil), nil
|
||||
}
|
||||
|
||||
// Decrypt decrypts the given bytes using the symmetric key
|
||||
func Decrypt(enc []byte) ([]byte, error) {
|
||||
// Sanity check on input
|
||||
if len(enc) < sharedGCM.NonceSize() {
|
||||
return nil, fmt.Errorf("failed to decrypt packet: too short")
|
||||
}
|
||||
|
||||
// Decrypt encrypted bytes
|
||||
return sharedGCM.Open(nil, enc[:nonceSize], enc[nonceSize:], nil)
|
||||
}
|
||||
@@ -76,9 +76,20 @@ func handle(conn net.Conn, outputDirectory string) {
|
||||
// Read raw content
|
||||
cont, contErr := ioutil.ReadAll(conn) // bufio.NewReader(conn).ReadString('\x00')
|
||||
|
||||
// Check if we are able to decrypt
|
||||
if CryptApplicable() {
|
||||
// Decrypt packet
|
||||
var decryptErr error
|
||||
cont, decryptErr = Decrypt(cont)
|
||||
if decryptErr != nil {
|
||||
log.Printf("Failed to decrypt packet from %s: %s", conn.RemoteAddr().String(), decryptErr)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if contErr == nil || contErr == io.EOF {
|
||||
// We received the whole content, time to process it
|
||||
unpackErr := logistic.UnpackInto([]byte(cont), outputDirectory)
|
||||
unpackErr := logistic.UnpackInto(cont, outputDirectory)
|
||||
if unpackErr != nil {
|
||||
log.Printf("Encountered error processing packet from %s: %s", conn.RemoteAddr().String(), unpackErr)
|
||||
}
|
||||
|
||||
11
net/peer.go
11
net/peer.go
@@ -37,6 +37,17 @@ func CreatePeer(address string) Peer {
|
||||
|
||||
// Sends the given content to the peer
|
||||
func (p *Peer) SendToPeer(content []byte) {
|
||||
// Encrypt content if desired
|
||||
if CryptApplicable() {
|
||||
// Encrypt packet
|
||||
var encryptErr error
|
||||
content, encryptErr = Encrypt(content)
|
||||
if encryptErr != nil {
|
||||
log.Printf("Failed to decrypt packet from %s: %s", p.Address, encryptErr)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Build up a connection
|
||||
tcpConn, dialErr := net.Dial("tcp", p.Address)
|
||||
if dialErr != nil {
|
||||
|
||||
Reference in New Issue
Block a user