veyron/security/agent: Added encryption to agent and option not
to encrypt.
* Password will only be requested when the PEM Block is not encrypted.
* Next step is to change the agent from a signer to a principal. Coming
soon...
Change-Id: I811bb6af636d83243052465039192c7bfa307cc1
diff --git a/security/principal_test.go b/security/principal_test.go
index a8ad464..d2d18ce 100644
--- a/security/principal_test.go
+++ b/security/principal_test.go
@@ -1,38 +1,105 @@
package security
import (
+ "crypto/ecdsa"
+ "crypto/elliptic"
+ "crypto/rand"
"io/ioutil"
"os"
+ "path"
"testing"
)
-func TestNewPersistentPrincipal(t *testing.T) {
+func TestLoadPersistentPrincipal(t *testing.T) {
+ // If the directory does not exist want os.IsNotExists.
+ _, err := LoadPersistentPrincipal("/tmp/fake/path/", nil)
+ if !os.IsNotExist(err) {
+ t.Errorf("invalid path should return does not exist error, instead got %v", err)
+ }
+ // If the key file exists and is unencrypted we should succeed.
+ dir := generatePEMFile(nil)
+ if _, err = LoadPersistentPrincipal(dir, nil); err != nil {
+ t.Errorf("unencrypted LoadPersistentPrincipal should have succeeded: %v", err)
+ }
+ os.RemoveAll(dir)
+
+ // If the private key file exists and is encrypted we should succeed with correct passphrase.
+ passphrase := []byte("passphrase")
+ incorrect_passphrase := []byte("incorrect_passphrase")
+ dir = generatePEMFile(passphrase)
+ if _, err = LoadPersistentPrincipal(dir, passphrase); err != nil {
+ t.Errorf("encrypted LoadPersistentPrincipal should have succeeded: %v", err)
+ }
+ // and fail with an incorrect passphrase.
+ if _, err = LoadPersistentPrincipal(dir, incorrect_passphrase); err == nil {
+ t.Errorf("encrypted LoadPersistentPrincipal with incorrect passphrase should fail")
+ }
+ // and return MissingPassphraseError if the passphrase is nil.
+ if _, err = LoadPersistentPrincipal(dir, nil); err != MissingPassphraseErr {
+ t.Errorf("encrypted LoadPersistentPrincipal with nil passphrase should return MissingPassphraseErr: %v", err)
+ }
+ os.RemoveAll(dir)
+}
+
+func TestCreatePersistentPrincipal(t *testing.T) {
+ tests := []struct {
+ Message, Passphrase []byte
+ }{
+ {[]byte("unencrypted"), nil},
+ {[]byte("encrypted"), []byte("passphrase")},
+ }
+ for _, test := range tests {
+ testCreatePersistentPrincipal(t, test.Message, test.Passphrase)
+ }
+}
+
+func testCreatePersistentPrincipal(t *testing.T, message, passphrase []byte) {
// Persistence of the BlessingRoots and BlessingStore objects is
// tested in other files. Here just test the persistence of the key.
- dir, err := ioutil.TempDir("", "TestNewPersistentPrincipal")
+ dir, err := ioutil.TempDir("", "TestCreatePersistentPrincipal")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(dir)
- p, existed, err := NewPersistentPrincipal(dir)
+ p, err := CreatePersistentPrincipal(dir, passphrase)
if err != nil {
t.Fatal(err)
}
- if existed {
- t.Fatalf("%q already has data", existed)
- }
- message := []byte("this is a test message")
sig, err := p.Sign(message)
if err != nil {
t.Fatal(err)
}
- p2, _, err := NewPersistentPrincipal(dir)
+ p2, err := CreatePersistentPrincipal(dir, passphrase)
+ if err == nil {
+ t.Errorf("p2 CreatePersistentPrincipal should have failed")
+ }
+ p2, err = LoadPersistentPrincipal(dir, passphrase)
if err != nil {
t.Fatal(err)
}
- if !sig.Verify(p2.PublicKey(), message) {
- t.Errorf("p.PublicKey=%v, p2.PublicKey=%v", p.PublicKey(), p2.PublicKey())
+ if !sig.Verify(p.PublicKey(), message) {
+ t.Errorf("%s failed: p.PublicKey=%v, p2.PublicKey=%v", message, p.PublicKey(), p2.PublicKey())
}
}
+
+func generatePEMFile(passphrase []byte) (dir string) {
+ dir, err := ioutil.TempDir("", "TestLoadPersistentPrincipal")
+ if err != nil {
+ panic(err)
+ }
+ key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+ if err != nil {
+ panic(err)
+ }
+ f, err := os.Create(path.Join(dir, privateKeyFile))
+ if err != nil {
+ panic(err)
+ }
+ defer f.Close()
+ if err = savePEMKey(f, key, passphrase); err != nil {
+ panic(err)
+ }
+ return dir
+}