Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/agent/request.go b/agent/request.go
- index c539ca2..89648d2 100644
- --- a/agent/request.go
- +++ b/agent/request.go
- @@ -23,6 +23,9 @@ type Request struct {
- StorePlugin string `json:"store_plugin"`
- StoreEndpoint string `json:"store_endpoint"`
- RestoreKey string `json:"restore_key"`
- + EncryptionMode string `json:"encryption_mode"`
- + EncryptionKey string `json:"encryption_key"`
- + EncryptionIV string `json:"encryption_iv"`
- }
- func ParseRequestValue(value []byte) (*Request, error) {
- @@ -97,6 +100,12 @@ func (req *Request) Run(output chan string) error {
- log.Debugf("ENV: %s", strings.Join(cmd.Env, ","))
- + // set potentially sensitive things
- + // FIXME this is not secure and needs to be ripped out before we merge
- + cmd.Env = append(cmd.Env, "SHIELD_ENCRYPTION_MODE=%s", req.EncryptionMode)
- + cmd.Env = append(cmd.Env, "SHIELD_ENCRYPTION_KEY=%x", req.EncryptionKey)
- + cmd.Env = append(cmd.Env, "SHIELD_ENCRYPTION_IV=%x", req.EncryptionIV)
- +
- stdout, err := cmd.StdoutPipe()
- if err != nil {
- return err
- diff --git a/crypter/crypter.go b/crypter/crypter.go
- new file mode 100644
- index 0000000..1b1ca5c
- --- /dev/null
- +++ b/crypter/crypter.go
- @@ -0,0 +1,66 @@
- +package crypter
- +
- +import (
- + "crypto/aes"
- + "crypto/cipher"
- + "crypto/rand"
- + "fmt"
- + "io"
- + "strings"
- +
- + "golang.org/x/crypto/blowfish"
- + "golang.org/x/crypto/twofish"
- +)
- +
- +func Stream(enctype string, key, iv []byte) (cipher.Stream, cipher.Stream, error) {
- + // cipher-mode combinations included so far are:
- + // aes-cfb, blowfish-cfb, twofish-cfb
- + if enctype == "" {
- + return nil, nil, fmt.Errorf("No encryption type specified")
- + }
- + if !strings.Contains(enctype, "-") {
- + return nil, nil, fmt.Errorf("Invalid encryption type '%s' specified", enctype)
- + }
- + cipherName := strings.Split(enctype, "-")[0]
- + mode := strings.Split(enctype, "-")[1]
- +
- + var err error
- + var block cipher.Block
- +
- + switch cipherName {
- + // Was originally going to specify aes128 or aes256, but the keysize determines
- + // which is used.
- + case "aes128", "aes256": // should we pull 128-bit? FIXME
- + block, err = aes.NewCipher(key)
- + case "blowfish": // not recommended by its author; pull it? FIXME
- + block, err = blowfish.NewCipher(key)
- + case "twofish":
- + block, err = twofish.NewCipher(key)
- + default:
- + return nil, nil, fmt.Errorf("Invalid cipher '%s' specified", cipherName)
- + }
- +
- + if err != nil {
- + return nil, nil, err
- + }
- +
- + switch mode {
- + case "cfb":
- + return cipher.NewCFBEncrypter(block, iv), cipher.NewCFBDecrypter(block, iv), nil
- + case "ofb":
- + return cipher.NewOFB(block, iv), cipher.NewOFB(block, iv), nil
- + case "ctr":
- + return cipher.NewCTR(block, iv), cipher.NewCTR(block, iv), nil
- + default:
- + return nil, nil, fmt.Errorf("Invalid encryption mode '%s' specified", cipherName)
- + }
- +}
- +
- +func Initialize() (string, string, error) {
- + //Generate the random IV
- + iv := make([]byte, twofish.BlockSize)
- + if _, err := io.ReadFull(rand.Reader, iv); err != nil {
- + return "", "", err
- + }
- + return "", "", nil
- +}
- diff --git a/crypter/vault.go b/crypter/vault.go
- new file mode 100644
- index 0000000..b7942c2
- --- /dev/null
- +++ b/crypter/vault.go
- @@ -0,0 +1,3 @@
- +package crypter
- +
- +
- diff --git a/db/schema.go b/db/schema.go
- index 95f12f6..fb6aa6a 100644
- --- a/db/schema.go
- +++ b/db/schema.go
- @@ -12,6 +12,7 @@ var Schemas = map[int]Schema{
- 1: v1Schema{},
- 2: v2Schema{},
- 3: v3Schema{},
- + 4: v4Schema{},
- }
- type Schema interface {
- diff --git a/db/schema_v4.go b/db/schema_v4.go
- new file mode 100644
- index 0000000..893f34d
- --- /dev/null
- +++ b/db/schema_v4.go
- @@ -0,0 +1,14 @@
- +package db
- +
- +type v4Schema struct{}
- +
- +func (s v4Schema) Deploy(db *DB) error {
- + var err error
- +
- + err = db.Exec(`ALTER TABLE archives ADD COLUMN encryption_mode VARCHAR(50)`)
- + if err != nil {
- + return err
- + }
- +
- + return nil
- +}
- diff --git a/plugin/exec.go b/plugin/exec.go
- index 0107e3f..afa53a8 100644
- --- a/plugin/exec.go
- +++ b/plugin/exec.go
- @@ -1,11 +1,16 @@
- package plugin
- import (
- + "encoding/hex"
- "fmt"
- - "github.com/mattn/go-shellwords"
- + "io"
- "os"
- "os/exec"
- "syscall"
- +
- + "crypto/cipher"
- + "github.com/mattn/go-shellwords"
- + "github.com/starkandwayne/shield/crypter"
- )
- const NOPIPE = 0
- @@ -13,8 +18,8 @@ const STDIN = 1
- const STDOUT = 2
- type ExecOptions struct {
- - Stdout *os.File
- - Stdin *os.File
- + Stdout io.Writer
- + Stdin io.Reader
- Stderr *os.File
- Cmd string
- ExpectRC []int
- @@ -27,15 +32,39 @@ func ExecWithOptions(opts ExecOptions) error {
- }
- DEBUG("Executing '%s' with arguments %v", cmdArgs[0], cmdArgs[1:])
- + // some liberties will be taken here. hang on!
- + keyRaw, err := hex.DecodeString(os.Getenv("SHIELD_ENCRYPTION_KEY"))
- + if err != nil {
- + return err
- + }
- + ivRaw, err := hex.DecodeString(os.Getenv("SHIELD_ENCRYPTION_IV"))
- + if err != nil {
- + return err
- + }
- + // keyRaw := "\xDE\xAD\xBE\xEF\xDE\xCA\xFB\xAD\xDE\xAD\xBE\xEF\xDE\xCA\xFB\xAD"
- + // ivRaw := "\xCA\xFE\xBA\xBE\xAB\xAD\x1D\xEA"
- + // ivRaw = keyRaw
- +
- + encStream, decStream, err := crypter.Stream(os.Getenv("SHIELD_ENCRYPTION_TYPE"), keyRaw, ivRaw)
- + if err != nil {
- + return err
- + }
- cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)
- if opts.Stdout != nil {
- - cmd.Stdout = opts.Stdout
- + cmd.Stdout = cipher.StreamWriter{
- + S: encStream,
- + W: opts.Stdout,
- + }
- }
- if opts.Stderr != nil {
- cmd.Stderr = opts.Stderr
- }
- if opts.Stdin != nil {
- cmd.Stdin = opts.Stdin
- + cmd.Stdin = cipher.StreamReader{
- + S: decStream,
- + R: opts.Stdin,
- + }
- }
- if len(opts.ExpectRC) == 0 {
- @@ -78,6 +107,5 @@ func Exec(cmdString string, flags int) error {
- if flags&STDIN == STDIN {
- opts.Stdin = os.Stdin
- }
- -
- return ExecWithOptions(opts)
- }
- diff --git a/plugin/exec_test.go b/plugin/exec_test.go
- index b9a3342..a46e4b3 100644
- --- a/plugin/exec_test.go
- +++ b/plugin/exec_test.go
- @@ -12,6 +12,11 @@ import (
- )
- var _ = Describe("Plugin Commands", func() {
- + BeforeEach(func() {
- + os.Setenv("SHIELD_ENCRYPTION_KEY", "DEADBEEFDECAFBADDEADBEEFDECAFBAD")
- + os.Setenv("SHIELD_ENCRYPTION_IV", "DEADBEEFDECAFBADDEADBEEFDECAFBAD")
- + os.Setenv("SHIELD_ENCRYPTION_TYPE", "aes256-ctr")
- + })
- drain := func(file *os.File, output chan string) {
- data, err := ioutil.ReadAll(file)
- diff --git a/run b/run
- new file mode 100755
- index 0000000..0d02a93
- --- /dev/null
- +++ b/run
- @@ -0,0 +1,54 @@
- +#!/bin/bash
- +set -u
- +
- +export LC_ALL=C
- +
- +export DEBUG=1
- +ENDPOINT='{"data":"i am secret information"}'
- +PLUGIN=dummy
- +
- +KEY=DEADBEEFDECAFBADDEADBEEFDECAFBAD
- +IV=${KEY}
- +
- +export SHIELD_ENCRYPTION_TYPE="aes256-ctr"
- +export SHIELD_ENCRYPTION_KEY="$KEY"
- +export SHIELD_ENCRYPTION_IV="$IV"
- +
- +#./$PLUGIN validate -e "${ENDPOINT}"
- +./$PLUGIN backup -e "${ENDPOINT}" > out.enc
- +
- +echo
- +echo "----------------------"
- +echo
- +
- +(echo "i am secret information" | \
- + openssl enc -aes-256-ctr -nosalt \
- + -nopad -K $KEY -iv $IV) > out.ssl
- +
- +echo "from out.ssl (via openssl):"
- +echo "----------------------"
- +openssl enc -aes-256-ctr -d -nosalt \
- + -nopad -K $KEY -iv $IV < out.ssl
- +echo "----------------------"
- +
- +echo
- +echo "from out.enc (via openssl):"
- +echo "----------------------"
- +openssl enc -aes-256-ctr -d -nosalt \
- + -nopad -K $KEY -iv $IV < out.enc | od -a
- +echo "----------------------"
- +
- +echo "SHA sum of out.*:"
- +echo "----------------------"
- +shasum out.*
- +echo "----------------------"
- +
- +echo
- +echo "restore op:"
- +echo "----------------------"
- +cat out.enc | ./$PLUGIN restore -e '{"file":"restored.out"}'
- +cat restored.out
- +echo "----------------------"
- +
- +echo "ALL DONE!"
- +exit 0
- diff --git a/supervisor/worker.go b/supervisor/worker.go
- index 76fc113..66af5a0 100644
- --- a/supervisor/worker.go
- +++ b/supervisor/worker.go
- @@ -40,6 +40,9 @@ type WorkerRequest struct {
- StorePlugin string `json:"store_plugin"`
- StoreEndpoint string `json:"store_endpoint"`
- RestoreKey string `json:"restore_key"`
- + EncryptionMode string `json:"encryption_mode"`
- + EncryptionKey string `json:"encryption_key"`
- + EncryptionIV string `json:"encryption_iv"`
- }
- func worker(id uint, privateKeyFile string, work chan *db.Task, updates chan WorkerUpdate) {
- @@ -103,6 +106,9 @@ func worker(id uint, privateKeyFile string, work chan *db.Task, updates chan Wor
- StorePlugin: t.StorePlugin,
- StoreEndpoint: t.StoreEndpoint,
- RestoreKey: t.RestoreKey,
- + EncryptionMode: "aes256-ctr",
- + EncryptionKey: "\xDE\xAD\xBE\xEF\xDE\xCA\xFB\xAD\xDE\xAD\xBE\xEF\xDE\xCA\xFB\xAD\xDE\xAD\xBE\xEF\xDE\xCA\xFB\xAD\xDE\xAD\xBE\xEF\xDE\xCA\xFB\xAD",
- + EncryptionIV: "\xCA\xFE\xBA\xBE\xAB\xAD\x1D\xEA\xCA\xFE\xBA\xBE\xAB\xAD\x1D\xEA",
- })
- if err != nil {
- updates <- WorkerUpdate{Task: t.UUID, Op: OUTPUT,
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement