From 6507afd3ada3376be784cb4899f2fa58a04633ae Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 12 Dec 2013 16:59:33 -0800 Subject: [PATCH] builder/googlecompute: private key tests --- builder/googlecompute/private_key.go | 8 ++- builder/googlecompute/private_key_test.go | 78 +++++++++++++++++++++++ 2 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 builder/googlecompute/private_key_test.go diff --git a/builder/googlecompute/private_key.go b/builder/googlecompute/private_key.go index 91f6a25e6..476d71a9e 100644 --- a/builder/googlecompute/private_key.go +++ b/builder/googlecompute/private_key.go @@ -8,29 +8,35 @@ import ( "io/ioutil" ) -// processPrivateKeyFile. +// processPrivateKeyFile takes a private key file and an optional passphrase +// and decodes it to a byte slice. func processPrivateKeyFile(privateKeyFile, passphrase string) ([]byte, error) { rawPrivateKeyBytes, err := ioutil.ReadFile(privateKeyFile) if err != nil { return nil, fmt.Errorf("Failed loading private key file: %s", err) } + PEMBlock, _ := pem.Decode(rawPrivateKeyBytes) if PEMBlock == nil { return nil, fmt.Errorf("%s does not contain a vaild private key", privateKeyFile) } + if x509.IsEncryptedPEMBlock(PEMBlock) { if passphrase == "" { return nil, errors.New("a passphrase must be specified when using an encrypted private key") } + decryptedPrivateKeyBytes, err := x509.DecryptPEMBlock(PEMBlock, []byte(passphrase)) if err != nil { return nil, fmt.Errorf("Failed decrypting private key: %s", err) } + b := &pem.Block{ Type: "RSA PRIVATE KEY", Bytes: decryptedPrivateKeyBytes, } return pem.EncodeToMemory(b), nil } + return rawPrivateKeyBytes, nil } diff --git a/builder/googlecompute/private_key_test.go b/builder/googlecompute/private_key_test.go new file mode 100644 index 000000000..ad0a3bfd0 --- /dev/null +++ b/builder/googlecompute/private_key_test.go @@ -0,0 +1,78 @@ +package googlecompute + +import ( + "crypto/rand" + "crypto/x509" + "encoding/pem" + "io/ioutil" + "os" + "testing" +) + +func testPrivateKeyFile(t *testing.T) string { + tf, err := ioutil.TempFile("", "packer") + if err != nil { + t.Fatalf("bad: %s", err) + } + defer tf.Close() + + b := &pem.Block{ + Type: "RSA PRIVATE KEY", + Bytes: []byte("what"), + } + + if err := pem.Encode(tf, b); err != nil { + t.Fatalf("err: %s", err) + } + + return tf.Name() +} + +func TestProcesssPrivateKeyFile(t *testing.T) { + path := testPrivateKeyFile(t) + defer os.Remove(path) + + data, err := processPrivateKeyFile(path, "") + if err != nil { + t.Fatalf("err: %s", err) + } + + if len(data) <= 0 { + t.Fatalf("bad: %#v", data) + } +} + +func TestProcessPrivateKeyFile_encrypted(t *testing.T) { + // Encrypt the file + b, err := x509.EncryptPEMBlock(rand.Reader, + "RSA PRIVATE KEY", + []byte("what"), + []byte("password"), + x509.PEMCipherAES128) + if err != nil { + t.Fatalf("err: %s", err) + } + + tf, err := ioutil.TempFile("", "packer") + if err != nil { + t.Fatalf("bad: %s", err) + } + defer os.Remove(tf.Name()) + + err = pem.Encode(tf, b) + tf.Close() + if err != nil { + t.Fatalf("err: %s", err) + } + + path := tf.Name() + + // Should have an error with a bad password + if _, err := processPrivateKeyFile(path, "bad"); err == nil { + t.Fatal("should error") + } + + if _, err := processPrivateKeyFile(path, "password"); err != nil { + t.Fatalf("bad: %s", err) + } +}