initial aead

Signed-off-by: Jess Frazelle <jess@mesosphere.com>
This commit is contained in:
Jess Frazelle 2016-04-18 01:09:18 -07:00
parent dc8799e280
commit f11dd855bc
No known key found for this signature in database
GPG key ID: 18F3685C0022BFF3
5 changed files with 127 additions and 8 deletions

View file

@ -48,7 +48,7 @@ image.tar:
docker export $(shell docker create $(DOCKER_ROOTFS_IMAGE) sh) > $@ docker export $(shell docker create $(DOCKER_ROOTFS_IMAGE) sh) > $@
rootfs.go: image.tar rootfs.go: image.tar
GOMAXPROCS=1 go generate GOMAXPROCS=1 go run generate.go
fmt: fmt:
@echo "+ $@" @echo "+ $@"

91
cryptar/cryptar.go Normal file
View file

@ -0,0 +1,91 @@
package cryptar
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/base64"
)
// Encrypt takes the contents of a tarball and a key and seals it.
func Encrypt(tarball, key []byte) (string, error) {
gcm, err := keyToGCM(key)
if err != nil {
return "", err
}
nonce, err := generateNonce(gcm.NonceSize())
if err != nil {
return "", err
}
out := gcm.Seal(nonce, nonce, tarball, nil)
enctar := base64.StdEncoding.EncodeToString(out)
return enctar, nil
}
// Decrypt takes an encrypted tarball and key and unseals it.
func Decrypt(enctar string, key []byte) ([]byte, error) {
out, err := base64.StdEncoding.DecodeString(enctar)
if err != nil {
return nil, err
}
gcm, err := keyToGCM(key)
if err != nil {
return nil, err
}
size := gcm.NonceSize()
nonce := make([]byte, size)
copy(nonce, out[:])
tarball, err := gcm.Open(nil, nonce, out[size:], nil)
if err != nil {
return nil, err
}
return tarball, nil
}
func keyToGCM(key []byte) (cipher.AEAD, error) {
/*hash := sha256.New()
if _, err := hash.Write([]byte(key)); err != nil {
return nil, err
}
md := hash.Sum(nil)
mdkey := hex.EncodeToString(md)*/
// encrypt the tar with the key
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
gcm, err := cipher.NewGCM(block)
if err != nil {
return nil, err
}
return gcm, err
}
// generateNonce creates a new random nonce.
func generateNonce(size int) ([]byte, error) {
// Create the nonce.
nonce, err := randBytes(size)
if err != nil {
return nil, err
}
return nonce, nil
}
// randBytes returns n bytes of random data.
func randBytes(n int) ([]byte, error) {
b := make([]byte, n)
_, err := rand.Read(b)
return b, err
}

View file

@ -3,14 +3,22 @@
package main package main
import ( import (
"crypto/rand"
"encoding/base64" "encoding/base64"
"fmt"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"github.com/jfrazelle/binctr/cryptar"
)
const (
nonceSize = 24
) )
// Reads static/index.html and saves as a constant in static.go
func main() { func main() {
// prompt for key
wd, err := os.Getwd() wd, err := os.Getwd()
if err != nil { if err != nil {
panic(err) panic(err)
@ -22,15 +30,27 @@ func main() {
tarPath := filepath.Join(wd, "image.tar") tarPath := filepath.Join(wd, "image.tar")
out.Write([]byte("// This file is autogenerated; DO NOT EDIT DIRECTLY\n// See generate.go for more info\npackage main\n\nconst (\n")) out.Write([]byte("// This file is autogenerated; DO NOT EDIT DIRECTLY\n// See generate.go for more info\npackage main\n\nconst (\n"))
out.Write([]byte("\t// DATA is the encrypted tarball data\n"))
out.Write([]byte("\tDATA = `")) out.Write([]byte("\tDATA = `"))
f, err := ioutil.ReadFile(tarPath) f, err := ioutil.ReadFile(tarPath)
if err != nil { if err != nil {
panic(err) panic(err)
} }
tar := base64.StdEncoding.EncodeToString(f) key := make([]byte, 32)
out.Write([]byte(tar)) if _, err := rand.Read(key); err != nil {
panic(err)
}
gcmOut, err := cryptar.Encrypt(f, key)
if err != nil {
panic(err)
}
out.Write([]byte(gcmOut))
out.Write([]byte("`\n")) out.Write([]byte("`\n"))
out.Write([]byte(")\n")) out.Write([]byte(")\n"))
fmt.Println("key is: ", base64.StdEncoding.EncodeToString(key))
} }

View file

@ -34,7 +34,7 @@ const (
` `
defaultRoot = "/run/binctr" defaultRoot = "/tmp/binctr"
defaultRootfsDir = "rootfs" defaultRootfsDir = "rootfs"
defaultApparmorProfile = "docker-default" defaultApparmorProfile = "docker-default"
) )
@ -44,6 +44,7 @@ var (
containerID string containerID string
pidFile string pidFile string
root string root string
passkey string
allocateTty bool allocateTty bool
detach bool detach bool
@ -116,6 +117,7 @@ func init() {
flag.StringVar(&console, "console", console, "the pty slave path for use with the container") flag.StringVar(&console, "console", console, "the pty slave path for use with the container")
flag.StringVar(&pidFile, "pid-file", "", "specify the file to write the process id to") flag.StringVar(&pidFile, "pid-file", "", "specify the file to write the process id to")
flag.StringVar(&root, "root", defaultRoot, "root directory of container state, should be tmpfs") flag.StringVar(&root, "root", defaultRoot, "root directory of container state, should be tmpfs")
flag.StringVar(&passkey, "key", "", "key to decrypt the embedded tarball")
flag.Var(&hookflags, "hook", "Hooks to prefill into spec file. (ex. --hook prestart:netns)") flag.Var(&hookflags, "hook", "Hooks to prefill into spec file. (ex. --hook prestart:netns)")
@ -215,7 +217,7 @@ func main() {
}, },
} }
if err := unpackRootfs(spec); err != nil { if err := unpackRootfs(spec, passkey); err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }

View file

@ -6,11 +6,17 @@ import (
"os" "os"
"github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/archive"
"github.com/jfrazelle/binctr/cryptar"
"github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/runtime-spec/specs-go"
) )
func unpackRootfs(spec *specs.Spec) error { func unpackRootfs(spec *specs.Spec, keyin string) error {
data, err := base64.StdEncoding.DecodeString(DATA) key, err := base64.StdEncoding.DecodeString(keyin)
if err != nil {
return err
}
data, err := cryptar.Decrypt(DATA, key)
if err != nil { if err != nil {
return err return err
} }