Package config

This commit is contained in:
Adrian Gallagher
2017-03-16 14:36:42 +11:00
parent b6c9d64f75
commit 3edf81f48b
24 changed files with 163 additions and 220 deletions

View File

@@ -1,21 +1,11 @@
package main
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/json"
"errors"
"flag"
"fmt"
"io"
"io/ioutil"
"log"
)
const (
ENCRYPTION_CONFIRMATION_STRING = "THORS-HAMMER"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
)
func EncryptOrDecrypt(encrypt bool) string {
@@ -38,26 +28,26 @@ func main() {
log.Println("GoCryptoTrader: config-helper tool.")
if key == "" {
result, err := PromptForConfigKey()
result, err := config.PromptForConfigKey()
if err != nil {
log.Fatal("Unable to obtain encryption/decryption key.")
}
key = string(result)
}
file, err := ReadFile(inFile)
file, err := common.ReadFile(inFile)
if err != nil {
log.Fatalf("Unable to read input file %s. Error: %s.", inFile, err)
}
if ConfirmECS(file) && encrypt {
if config.ConfirmECS(file) && encrypt {
log.Println("File is already encrypted. Decrypting..")
encrypt = false
}
if !ConfirmECS(file) && !encrypt {
if !config.ConfirmECS(file) && !encrypt {
var result interface{}
err := ConfirmConfigJSON(file, result)
err := config.ConfirmConfigJSON(file, result)
if err != nil {
log.Fatal("File isn't in JSON format")
}
@@ -67,119 +57,20 @@ func main() {
var data []byte
if encrypt {
data, err = EncryptConfigFile(file, []byte(key))
data, err = config.EncryptConfigFile(file, []byte(key))
if err != nil {
log.Fatalf("Unable to encrypt config data. Error: %s.", err)
}
} else {
data, err = DecryptConfigFile(file, []byte(key))
data, err = config.DecryptConfigFile(file, []byte(key))
if err != nil {
log.Fatalf("Unable to decrypt config data. Error: %s.", err)
}
}
err = WriteFile(outFile, data)
err = common.WriteFile(outFile, data)
if err != nil {
log.Fatalf("Unable to write output file %s. Error: %s", outFile, err)
}
log.Printf("Successfully %s input file %s and wrote output to %s.\n", EncryptOrDecrypt(encrypt), inFile, outFile)
}
func ReadFile(path string) ([]byte, error) {
file, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
return file, nil
}
func WriteFile(file string, data []byte) error {
err := ioutil.WriteFile(file, data, 0644)
if err != nil {
return err
}
return nil
}
func PromptForConfigKey() ([]byte, error) {
var cryptoKey []byte
for len(cryptoKey) != 32 {
log.Println("Enter password (32 characters):")
_, err := fmt.Scanln(&cryptoKey)
if err != nil {
return nil, err
}
if len(cryptoKey) > 32 || len(cryptoKey) < 32 {
continue
}
}
nonce := make([]byte, 12)
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
return nil, err
}
return cryptoKey, nil
}
func EncryptConfigFile(configData, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
ciphertext := make([]byte, aes.BlockSize+len(configData))
iv := ciphertext[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
return nil, err
}
stream := cipher.NewCFBEncrypter(block, iv)
stream.XORKeyStream(ciphertext[aes.BlockSize:], configData)
appendedFile := []byte(ENCRYPTION_CONFIRMATION_STRING)
appendedFile = append(appendedFile, ciphertext...)
return appendedFile, nil
}
func DecryptConfigFile(configData, key []byte) ([]byte, error) {
configData = RemoveECS(configData)
blockDecrypt, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
if len(configData) < aes.BlockSize {
return nil, errors.New("The config file data is too small for the AES required block size.")
}
iv := configData[:aes.BlockSize]
configData = configData[aes.BlockSize:]
stream := cipher.NewCFBDecrypter(blockDecrypt, iv)
stream.XORKeyStream(configData, configData)
result := configData
return result, nil
}
func ConfirmConfigJSON(file []byte, result interface{}) error {
err := json.Unmarshal(file, &result)
if err != nil {
return err
}
return nil
}
func ConfirmECS(file []byte) bool {
subslice := []byte(ENCRYPTION_CONFIRMATION_STRING)
return bytes.Contains(file, subslice)
}
func RemoveECS(file []byte) []byte {
return bytes.Trim(file, ENCRYPTION_CONFIRMATION_STRING)
}