initial aead
Signed-off-by: Jess Frazelle <jess@mesosphere.com>
This commit is contained in:
parent
dc8799e280
commit
f11dd855bc
5 changed files with 127 additions and 8 deletions
2
Makefile
2
Makefile
|
@ -48,7 +48,7 @@ image.tar:
|
|||
docker export $(shell docker create $(DOCKER_ROOTFS_IMAGE) sh) > $@
|
||||
|
||||
rootfs.go: image.tar
|
||||
GOMAXPROCS=1 go generate
|
||||
GOMAXPROCS=1 go run generate.go
|
||||
|
||||
fmt:
|
||||
@echo "+ $@"
|
||||
|
|
91
cryptar/cryptar.go
Normal file
91
cryptar/cryptar.go
Normal 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
|
||||
}
|
26
generate.go
26
generate.go
|
@ -3,14 +3,22 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/jfrazelle/binctr/cryptar"
|
||||
)
|
||||
|
||||
const (
|
||||
nonceSize = 24
|
||||
)
|
||||
|
||||
// Reads static/index.html and saves as a constant in static.go
|
||||
func main() {
|
||||
// prompt for key
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
@ -22,15 +30,27 @@ func main() {
|
|||
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("\t// DATA is the encrypted tarball data\n"))
|
||||
out.Write([]byte("\tDATA = `"))
|
||||
f, err := ioutil.ReadFile(tarPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
tar := base64.StdEncoding.EncodeToString(f)
|
||||
out.Write([]byte(tar))
|
||||
key := make([]byte, 32)
|
||||
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"))
|
||||
|
||||
fmt.Println("key is: ", base64.StdEncoding.EncodeToString(key))
|
||||
}
|
||||
|
|
6
main.go
6
main.go
|
@ -34,7 +34,7 @@ const (
|
|||
|
||||
`
|
||||
|
||||
defaultRoot = "/run/binctr"
|
||||
defaultRoot = "/tmp/binctr"
|
||||
defaultRootfsDir = "rootfs"
|
||||
defaultApparmorProfile = "docker-default"
|
||||
)
|
||||
|
@ -44,6 +44,7 @@ var (
|
|||
containerID string
|
||||
pidFile string
|
||||
root string
|
||||
passkey string
|
||||
|
||||
allocateTty 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(&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(&passkey, "key", "", "key to decrypt the embedded tarball")
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
|
|
@ -6,11 +6,17 @@ import (
|
|||
"os"
|
||||
|
||||
"github.com/docker/docker/pkg/archive"
|
||||
"github.com/jfrazelle/binctr/cryptar"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
func unpackRootfs(spec *specs.Spec) error {
|
||||
data, err := base64.StdEncoding.DecodeString(DATA)
|
||||
func unpackRootfs(spec *specs.Spec, keyin string) error {
|
||||
key, err := base64.StdEncoding.DecodeString(keyin)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
data, err := cryptar.Decrypt(DATA, key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue