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/lib/testutil/security/util.go b/lib/testutil/security/util.go
index 2bf1fdb..f43789e 100644
--- a/lib/testutil/security/util.go
+++ b/lib/testutil/security/util.go
@@ -24,9 +24,11 @@
 	if err != nil {
 		panic(err)
 	}
-	p, _, err := vsecurity.NewPersistentPrincipal(dir)
+	p, err := vsecurity.LoadPersistentPrincipal(dir, nil)
 	if err != nil {
-		panic(err)
+		if p, err = vsecurity.CreatePersistentPrincipal(dir, nil); err != nil {
+			panic(err)
+		}
 	}
 	blessings, err := parent.Bless(p.PublicKey(), parent.BlessingStore().Default(), name, security.UnconstrainedUse())
 	if err != nil {
diff --git a/lib/testutil/security/util_test.go b/lib/testutil/security/util_test.go
index 06ed969..a62d65a 100644
--- a/lib/testutil/security/util_test.go
+++ b/lib/testutil/security/util_test.go
@@ -21,12 +21,8 @@
 
 	parent := r.Principal()
 	childdir := NewVeyronCredentials(parent, "child")
-	_, existed, err := vsecurity.NewPersistentPrincipal(childdir)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if !existed {
-		t.Fatalf("Expected NewVeyronCredentials to have populated the directory %q", childdir)
+	if _, err = vsecurity.LoadPersistentPrincipal(childdir, nil); err != nil {
+		t.Fatalf("Expected NewVeyronCredentials to have populated the directory %q: %v", childdir, err)
 	}
 	// TODO(ashankar,ataly): Figure out what APIs should we use for more detailed testing
 	// of the child principal, for example:
diff --git a/runtimes/google/rt/security.go b/runtimes/google/rt/security.go
index a61edc1..fb9935b 100644
--- a/runtimes/google/rt/security.go
+++ b/runtimes/google/rt/security.go
@@ -59,9 +59,12 @@
 		// TODO(ataly, ashankar): If multiple runtimes are getting
 		// initialized at the same time from the same VEYRON_CREDENTIALS
 		// we will need some kind of locking for the credential files.
-		var existed bool
-		if rt.principal, existed, err = vsecurity.NewPersistentPrincipal(dir); err != nil {
-			return err
+		existed := true
+		if rt.principal, err = vsecurity.LoadPersistentPrincipal(dir, nil); err != nil {
+			existed = false
+			if rt.principal, err = vsecurity.CreatePersistentPrincipal(dir, nil); err != nil {
+				return err
+			}
 		}
 		if !existed {
 			return initDefaultBlessings(rt.principal)
diff --git a/security/agent/agentd/main.go b/security/agent/agentd/main.go
index 8e64de8..4ae6e0a 100644
--- a/security/agent/agentd/main.go
+++ b/security/agent/agentd/main.go
@@ -1,31 +1,45 @@
 package main
 
 import (
+	"code.google.com/p/gopass"
 	"flag"
 	"fmt"
 	"os"
 	"os/exec"
 	"syscall"
-
-	"veyron.io/veyron/veyron2/rt"
-
 	_ "veyron.io/veyron/veyron/profiles"
+	vsecurity "veyron.io/veyron/veyron/security"
 	"veyron.io/veyron/veyron/security/agent"
 	"veyron.io/veyron/veyron/security/agent/server"
+
+	"veyron.io/veyron/veyron2/rt"
+	"veyron.io/veyron/veyron2/security"
+	"veyron.io/veyron/veyron2/vlog"
 )
 
 func main() {
 	flag.Usage = func() {
 		fmt.Fprintf(os.Stderr, `Usage: %s [agent options] command command_args...
 
-Loads the identity specified in VEYRON_IDENTITY into memory, then
-starts the specified command with access to the identity via the
+Loads the private key specified in under privatekey.pem in VEYRON_AGENT into memory, then
+starts the specified command with access to the private key via the
 agent protocol instead of directly reading from disk.
 
 `, os.Args[0])
 		flag.PrintDefaults()
 	}
-	// Load the identity specified in the environment
+	// TODO(suharshs): Switch to "VEYRON_CREDENTIALS" after agent is a principal.
+	// This will be the end of the old sec model here. Also change the comment above.
+	dir := os.Getenv("VEYRON_AGENT")
+	if len(dir) == 0 {
+		vlog.Fatal("VEYRON_AGENT must be set to directory")
+	}
+
+	p, err := newPrincipalFromDir(dir)
+	if err != nil {
+		vlog.Fatalf("failed to create new principal from dir(%s): %v", dir, err)
+	}
+
 	runtime := rt.Init()
 	log := runtime.Logger()
 
@@ -34,7 +48,6 @@
 		os.Exit(1)
 	}
 
-	var err error
 	if err = os.Setenv(agent.FdVarName, "3"); err != nil {
 		log.Fatalf("setenv: %v", err)
 	}
@@ -44,7 +57,7 @@
 
 	// Start running our server.
 	var sock *os.File
-	if sock, err = server.RunAnonymousAgent(runtime, runtime.Identity()); err != nil {
+	if sock, err = server.RunAnonymousAgent(runtime, p); err != nil {
 		log.Fatalf("RunAgent: %v", err)
 	}
 
@@ -64,3 +77,33 @@
 	status := cmd.ProcessState.Sys().(syscall.WaitStatus)
 	os.Exit(status.ExitStatus())
 }
+
+func newPrincipalFromDir(dir string) (security.Principal, error) {
+	p, err := vsecurity.LoadPersistentPrincipal(dir, nil)
+	if os.IsNotExist(err) {
+		return handleDoesNotExist(dir)
+	}
+	if err == vsecurity.MissingPassphraseErr {
+		return handleMissingPassphrase(dir)
+	}
+	return p, err
+}
+
+func handleDoesNotExist(dir string) (security.Principal, error) {
+	fmt.Println("Private key file does not exist. Creating new private key...")
+	pass, err := gopass.GetPass("Enter passphrase (entering nothing will store unecrypted): ")
+	if err != nil {
+		return nil, fmt.Errorf("failed to read passphrase: %v", err)
+	}
+	p, err := vsecurity.CreatePersistentPrincipal(dir, []byte(pass))
+	return p, err
+}
+
+func handleMissingPassphrase(dir string) (security.Principal, error) {
+	fmt.Println("Private key file is encrypted. Please enter passphrase.")
+	pass, err := gopass.GetPass("Enter passphrase: ")
+	if err != nil {
+		return nil, fmt.Errorf("failed to read passphrase: %v", err)
+	}
+	return vsecurity.LoadPersistentPrincipal(dir, []byte(pass))
+}
diff --git a/security/agent/server/server.go b/security/agent/server/server.go
index 0cf8759..3133501 100644
--- a/security/agent/server/server.go
+++ b/security/agent/server/server.go
@@ -22,6 +22,8 @@
 	"veyron.io/veyron/veyron2/vlog"
 )
 
+// TODO(suharshs): Remove this when replaced with principal. This is just temporary to
+// avoid having to implement a bunch of principal methods that aren't being used yet.
 type Signer interface {
 	Sign(message []byte) (security.Signature, error)
 	PublicKey() security.PublicKey
diff --git a/security/agent/test.sh b/security/agent/test.sh
index 4e14566..9ed0277 100755
--- a/security/agent/test.sh
+++ b/security/agent/test.sh
@@ -4,7 +4,7 @@
 
 source "${VEYRON_ROOT}/scripts/lib/shell_test.sh"
 
-readonly  WORKDIR="$(shell::tmp_dir)"
+readonly WORKDIR="$(shell::tmp_dir)"
 
 build() {
   veyron go build veyron.io/veyron/veyron/security/agent/agentd || shell_test::fail "line ${LINENO}: failed to build agentd"
@@ -23,6 +23,14 @@
   cd "${WORKDIR}"
   build
 
+  # TODO(suharshs): After switching to new security model this shoudl be VEYRON_CREDENTIALS.
+  export VEYRON_AGENT="$(shell::tmp_dir)"
+  echo "-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIGxO3M/KmUac35mffZAVZf0PcXj2qLj4AtTIxdSrAH1AoAoGCCqGSM49
+AwEHoUQDQgAEoZ4cgHtkSzP/PeUBLIOoSJWjx7t2cAWKxj+dd3AgDct2nJujM2+c
+dwwYdDyKjhBc2nacEDlvA3AqtCMU0c97hA==
+-----END EC PRIVATE KEY-----" > "${VEYRON_AGENT}/privatekey.pem"
+
   # TODO(ashankar): Remove this block (and remove the compilation of the identity tool)
   # once the agent has been updated to comply with the new security model.
   local -r ID=$(shell::tmp_file)
@@ -34,7 +42,6 @@
 
   # Test running a single app.
   shell_test::start_server ./pingpong --server
-  export VEYRON_PUBLICID_STORE="$(shell::tmp_dir)"
   ./agentd --v=4 ./pingpong || shell_test::fail "line ${LINENO}: failed to run pingpong"
   local -r OUTPUT=$(shell::tmp_file)
   RESULT=$(shell::check_result echo_identity "${OUTPUT}")
diff --git a/security/agent/test/main.go b/security/agent/test/main.go
index 6b9fbda..384011c 100644
--- a/security/agent/test/main.go
+++ b/security/agent/test/main.go
@@ -4,12 +4,13 @@
 	"flag"
 	"fmt"
 
-	"veyron.io/veyron/veyron2/ipc"
-	"veyron.io/veyron/veyron2/rt"
-
 	"veyron.io/veyron/veyron/lib/signals"
 	_ "veyron.io/veyron/veyron/profiles"
-	sflag "veyron.io/veyron/veyron/security/flag"
+	vsecurity "veyron.io/veyron/veyron/security"
+
+	"veyron.io/veyron/veyron2/ipc"
+	"veyron.io/veyron/veyron2/rt"
+	"veyron.io/veyron/veyron2/security"
 )
 
 var runServer = flag.Bool("server", false, "Whether to run in server mode")
@@ -54,7 +55,10 @@
 		log.Fatal("error listening to service: ", err)
 	}
 
-	if err := s.Serve("pingpong", ipc.LeafDispatcher(serverPong, sflag.NewAuthorizerOrDie())); err != nil {
+	auth := vsecurity.NewACLAuthorizer(security.ACL{In: map[security.BlessingPattern]security.LabelSet{
+		security.AllPrincipals: security.AllLabels,
+	}})
+	if err := s.Serve("pingpong", ipc.LeafDispatcher(serverPong, auth)); err != nil {
 		log.Fatal("error serving service: ", err)
 	}
 
diff --git a/security/blessingroots_test.go b/security/blessingroots_test.go
index c346126..899651c 100644
--- a/security/blessingroots_test.go
+++ b/security/blessingroots_test.go
@@ -97,13 +97,10 @@
 	}
 	defer os.RemoveAll(dir)
 	tester := newRootsTester()
-	p, existed, err := NewPersistentPrincipal(dir)
+	p, err := CreatePersistentPrincipal(dir, nil)
 	if err != nil {
 		t.Fatal(err)
 	}
-	if existed {
-		t.Fatalf("%q already has a principal", dir)
-	}
 	if err := tester.add(p.Roots()); err != nil {
 		t.Error(err)
 	}
@@ -111,7 +108,7 @@
 		t.Error(err)
 	}
 	// Recreate the principal (and thus BlessingRoots)
-	p2, _, err := NewPersistentPrincipal(dir)
+	p2, err := LoadPersistentPrincipal(dir, nil)
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/security/blessingstore_test.go b/security/blessingstore_test.go
index c7152bb..fd535d8 100644
--- a/security/blessingstore_test.go
+++ b/security/blessingstore_test.go
@@ -134,13 +134,10 @@
 		t.Fatal(err)
 	}
 	defer os.RemoveAll(dir)
-	p, existed, err := NewPersistentPrincipal(dir)
+	p, err := CreatePersistentPrincipal(dir, nil)
 	if err != nil {
 		t.Fatal(err)
 	}
-	if existed {
-		t.Errorf("%q already has a principal in it", dir)
-	}
 	tester := newStoreTester(p)
 	s := p.BlessingStore()
 
@@ -155,7 +152,7 @@
 	}
 
 	// Recreate the BlessingStore from the directory.
-	p2, _, err := NewPersistentPrincipal(dir)
+	p2, err := LoadPersistentPrincipal(dir, nil)
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/security/principal.go b/security/principal.go
index 3f5888e..c92430d 100644
--- a/security/principal.go
+++ b/security/principal.go
@@ -13,15 +13,6 @@
 
 const privateKeyFile = "privatekey.pem"
 
-// newKey generates an ECDSA (public, private) key pair..
-func newKey() (security.PublicKey, *ecdsa.PrivateKey, error) {
-	priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
-	if err != nil {
-		return nil, nil, err
-	}
-	return security.NewECDSAPublicKey(&priv.PublicKey), priv, nil
-}
-
 // NewPrincipal mints a new private key and generates a principal based on
 // this key, storing its BlessingRoots and BlessingStore in memory.
 func NewPrincipal() (security.Principal, error) {
@@ -32,69 +23,92 @@
 	return security.CreatePrincipal(security.NewInMemoryECDSASigner(priv), newInMemoryBlessingStore(pub), newInMemoryBlessingRoots())
 }
 
-// NewPersistentPrincipal reads state for a principal (private key, BlessingRoots, BlessingStore)
+// LoadPersistentPrincipal reads state for a principal (private key, BlessingRoots, BlessingStore)
 // from the provided directory 'dir' and commits all state changes to the same directory.
-//
-// If the directory does not contain state, then a new private key is minted and all state of
-// the principal is committed to 'dir'. If the directory does not exist, it is created.
-//
-// Returns the security.Principal implementation, a boolean that is set to true iff the directory
-// already contained a principal and any errors in initialization.
-func NewPersistentPrincipal(dir string) (principal security.Principal, existed bool, err error) {
+// If private key file does not exist then an error 'err' is returned such that os.IsNotExist(err) is true.
+// If private key file exists then 'passphrase' must be non-nil if the contents of the file are encrypted,
+// otherwise a MissingPassphraseErr is returned.
+func LoadPersistentPrincipal(dir string, passphrase []byte) (security.Principal, error) {
+	key, err := loadKeyFromDir(dir, passphrase)
+	if err != nil {
+		return nil, err
+	}
+	return newPersistentPrincipalFromKey(key, dir)
+}
+
+// CreatePersistentPrincipal creates a new principal (private key, BlessingRoots, BlessingStore) and commits all state changes to the provided directory.
+// The generated private key is serialized and saved encrypted if the 'passphrase' is non-nil, and unencrypted otherwise.
+// If the directory has any preexisting key, CreatePersistentPrincipal will return an error.
+// The specified directory may not exist, in which case it gets created by this function.
+func CreatePersistentPrincipal(dir string, passphrase []byte) (principal security.Principal, err error) {
 	if finfo, err := os.Stat(dir); err == nil {
 		if !finfo.IsDir() {
-			return nil, false, fmt.Errorf("%q is not a directory", dir)
+			return nil, fmt.Errorf("%q is not a directory", dir)
 		}
 	} else if err := os.MkdirAll(dir, 0700); err != nil {
-		return nil, false, fmt.Errorf("failed to create %q: %v", dir, err)
+		return nil, fmt.Errorf("failed to create %q: %v", dir, err)
 	}
-	key, existed, err := initKey(dir)
+	key, err := initKey(dir, nil)
 	if err != nil {
-		return nil, false, fmt.Errorf("could not initialize private key from credentials directory %v: %v", dir, err)
+		return nil, fmt.Errorf("could not initialize private key from credentials directory %v: %v", dir, err)
 	}
+	p, err := newPersistentPrincipalFromKey(key, dir)
+	return p, err
+}
+
+func loadKeyFromDir(dir string, passphrase []byte) (*ecdsa.PrivateKey, error) {
+	keyFile := path.Join(dir, privateKeyFile)
+	f, err := os.Open(keyFile)
+	if err != nil {
+		return nil, err
+	}
+	defer f.Close()
+	key, err := loadPEMKey(f, passphrase)
+	if err != nil {
+		return nil, err
+	}
+	return key.(*ecdsa.PrivateKey), nil
+}
+
+func newPersistentPrincipalFromKey(key *ecdsa.PrivateKey, dir string) (security.Principal, error) {
 	signer, err := security.CreatePrincipal(security.NewInMemoryECDSASigner(key), nil, nil)
 	if err != nil {
-		return nil, false, fmt.Errorf("failed to create serialization.Signer: %v", err)
+		return nil, fmt.Errorf("failed to create serialization.Signer: %v", err)
 	}
 	roots, err := newPersistingBlessingRoots(dir, signer)
 	if err != nil {
-		return nil, false, fmt.Errorf("failed to load BlessingRoots from %q: %v", dir, err)
+		return nil, fmt.Errorf("failed to load BlessingRoots from %q: %v", dir, err)
 	}
 	store, err := newPersistingBlessingStore(dir, signer)
 	if err != nil {
-		return nil, false, fmt.Errorf("failed to load BlessingStore from %q: %v", dir, err)
+		return nil, fmt.Errorf("failed to load BlessingStore from %q: %v", dir, err)
 	}
-	p, err := security.CreatePrincipal(security.NewInMemoryECDSASigner(key), store, roots)
-	return p, existed, err
+	return security.CreatePrincipal(security.NewInMemoryECDSASigner(key), store, roots)
 }
 
-func initKey(dir string) (*ecdsa.PrivateKey, bool, error) {
+// newKey generates an ECDSA (public, private) key pair.
+func newKey() (security.PublicKey, *ecdsa.PrivateKey, error) {
+	priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+	if err != nil {
+		return nil, nil, err
+	}
+	return security.NewECDSAPublicKey(&priv.PublicKey), priv, nil
+}
+
+func initKey(dir string, passphrase []byte) (*ecdsa.PrivateKey, error) {
 	keyFile := path.Join(dir, privateKeyFile)
-	if f, err := os.Open(keyFile); err == nil {
-		defer f.Close()
-		v, err := LoadPEMKey(f, nil)
-		if err != nil {
-			return nil, false, fmt.Errorf("failed to load PEM data from %q: %v", keyFile, v)
-		}
-		key, ok := v.(*ecdsa.PrivateKey)
-		if !ok {
-			return nil, false, fmt.Errorf("%q contains a %T, not an ECDSA private key", keyFile, v)
-		}
-		return key, true, nil
-	} else if !os.IsNotExist(err) {
-		return nil, false, fmt.Errorf("failed to read %q: %v", keyFile, err)
-	}
-	_, key, err := newKey()
+	// O_EXCL returns an error if file exists.
+	f, err := os.OpenFile(keyFile, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600)
 	if err != nil {
-		return nil, false, fmt.Errorf("failed to generate a private key: %v", err)
-	}
-	f, err := os.OpenFile(keyFile, os.O_WRONLY|os.O_CREATE, 0600)
-	if err != nil {
-		return nil, false, fmt.Errorf("failed to open %q for writing: %v", keyFile, err)
+		return nil, fmt.Errorf("failed to open %q for writing: %v", keyFile, err)
 	}
 	defer f.Close()
-	if err := SavePEMKey(f, key, nil); err != nil {
-		return nil, false, fmt.Errorf("failed to save private key to %q: %v", keyFile, err)
+	_, key, err := newKey()
+	if err != nil {
+		return nil, fmt.Errorf("failed to generate private key: %v", err)
 	}
-	return key, false, nil
+	if err := savePEMKey(f, key, passphrase); err != nil {
+		return nil, fmt.Errorf("failed to save private key to %q: %v", keyFile, err)
+	}
+	return key, nil
 }
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
+}
diff --git a/security/util.go b/security/util.go
index 0ae070f..175d49f 100644
--- a/security/util.go
+++ b/security/util.go
@@ -28,42 +28,50 @@
 	return acl
 }
 
-// LoadPEMKey loads a key from 'r', assuming that it was saved using SavePEMKey
-// and the specified passphrase 'passphrase'.
-// If passphrase is nil, the key will still be encrypted with a random salt, but
-// this will offer no protection as the salt is stored with the PEMKey.
-func LoadPEMKey(r io.Reader, passphrase []byte) (interface{}, error) {
-	pemKeyBytes, err := ioutil.ReadAll(r)
+var MissingPassphraseErr = errors.New("passphrase required for decrypting private key")
+
+// loadPEMKey loads a key from 'r'. passphrase should be non-nil if the key held in 'r' is
+// encrypted, otherwise a MissingPassphraseErr will be returned.
+// If the key held in 'r' is unencrypted, 'passphrase' will be ignored.
+func loadPEMKey(r io.Reader, passphrase []byte) (interface{}, error) {
+	pemBlockBytes, err := ioutil.ReadAll(r)
 	if err != nil {
 		return nil, err
 	}
-
-	pemKey, _ := pem.Decode(pemKeyBytes)
-	if pemKey == nil {
+	pemBlock, _ := pem.Decode(pemBlockBytes)
+	if pemBlock == nil {
 		return nil, errors.New("no PEM key block read")
 	}
-
-	data, err := x509.DecryptPEMBlock(pemKey, passphrase)
-	if err != nil {
-		return nil, err
+	var data []byte
+	if x509.IsEncryptedPEMBlock(pemBlock) {
+		if passphrase == nil {
+			return nil, MissingPassphraseErr
+		}
+		data, err = x509.DecryptPEMBlock(pemBlock, passphrase)
+		if err != nil {
+			return nil, err
+		}
+	} else {
+		data = pemBlock.Bytes
 	}
 
-	switch pemKey.Type {
+	switch pemBlock.Type {
 	case ecPrivateKeyPEMType:
 		return x509.ParseECPrivateKey(data)
 	}
-	return nil, fmt.Errorf("PEM key block has an unrecognized type: %v", pemKey.Type)
+	return nil, fmt.Errorf("PEM key block has an unrecognized type: %v", pemBlock.Type)
 }
 
-// SavePEMKey marshals 'key', encrypts it using 'passphrase', and saves the bytes to 'w' in PEM format.
+// savePEMKey marshals 'key', encrypts it using 'passphrase', and saves the bytes to 'w' in PEM format.
+// If passphrase is nil, the key will not be encrypted.
 //
 // For example, if key is an ECDSA private key, it will be marshaled
 // in ASN.1, DER format, encrypted, and then written in a PEM block.
-func SavePEMKey(w io.Writer, key interface{}, passphrase []byte) error {
+func savePEMKey(w io.Writer, key interface{}, passphrase []byte) error {
 	var data []byte
+	var err error
 	switch k := key.(type) {
 	case *ecdsa.PrivateKey:
-		var err error
 		if data, err = x509.MarshalECPrivateKey(k); err != nil {
 			return err
 		}
@@ -71,9 +79,17 @@
 		return fmt.Errorf("key of type %T cannot be saved", k)
 	}
 
-	pemKey, err := x509.EncryptPEMBlock(rand.Reader, ecPrivateKeyPEMType, data, passphrase, x509.PEMCipherAES256)
-	if err != nil {
-		return fmt.Errorf("failed to encrypt pem block: %v", err)
+	var pemKey *pem.Block
+	if passphrase != nil {
+		pemKey, err = x509.EncryptPEMBlock(rand.Reader, ecPrivateKeyPEMType, data, passphrase, x509.PEMCipherAES256)
+		if err != nil {
+			return fmt.Errorf("failed to encrypt pem block: %v", err)
+		}
+	} else {
+		pemKey = &pem.Block{
+			Type:  ecPrivateKeyPEMType,
+			Bytes: data,
+		}
 	}
 
 	return pem.Encode(w, pemKey)
diff --git a/security/util_test.go b/security/util_test.go
index bd55641..f4e2aec 100644
--- a/security/util_test.go
+++ b/security/util_test.go
@@ -5,6 +5,7 @@
 	"crypto/ecdsa"
 	"crypto/elliptic"
 	"crypto/rand"
+	"crypto/x509"
 	"fmt"
 	"reflect"
 	"testing"
@@ -20,47 +21,50 @@
 	}
 
 	var buf bytes.Buffer
-	if err := SavePEMKey(&buf, key, nil); err != nil {
+	if err := savePEMKey(&buf, key, nil); err != nil {
 		t.Fatalf("Failed to save ECDSA private key: %v", err)
 	}
 
-	loadedKey, err := LoadPEMKey(&buf, nil)
-	if err != nil {
-		t.Fatalf("Failed to load ECDSA private key: %v", err)
-	}
+	loadedKey, err := loadPEMKey(&buf, nil)
 	if !reflect.DeepEqual(loadedKey, key) {
 		t.Fatalf("Got key %v, but want %v", loadedKey, key)
 	}
 }
 
-func TestLoadSavePEMKeyWithPassword(t *testing.T) {
+func TestLoadSavePEMKeyWithPassphrase(t *testing.T) {
 	pass := []byte("openSesame")
-	incorrect_pass := []byte("wrongPassword")
+	incorrect_pass := []byte("wrongPassphrase")
 	key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
 	if err != nil {
 		t.Fatalf("Failed ecdsa.GenerateKey: %v", err)
 	}
 	var buf bytes.Buffer
-	// Test incorrect password.
-	if err := SavePEMKey(&buf, key, pass); err != nil {
+
+	// Test incorrect passphrase.
+	if err := savePEMKey(&buf, key, pass); err != nil {
 		t.Fatalf("Failed to save ECDSA private key: %v", err)
 	}
-	loadedKey, err := LoadPEMKey(&buf, incorrect_pass)
-	if err == nil {
-		t.Errorf("loaded ECDSA private key with incorrect password")
+	loadedKey, err := loadPEMKey(&buf, incorrect_pass)
+	if loadedKey != nil && err != x509.IncorrectPasswordError {
+		t.Errorf("expected (nil, x509.IncorrectPasswordError) received (%v,%v)", loadedKey, err)
 	}
 
 	// Test correct password.
-	if err := SavePEMKey(&buf, key, pass); err != nil {
+	if err := savePEMKey(&buf, key, pass); err != nil {
 		t.Fatalf("Failed to save ECDSA private key: %v", err)
 	}
-	loadedKey, err = LoadPEMKey(&buf, pass)
-	if err != nil {
-		t.Fatalf("Failed to load ECDSA private key: %v", err)
-	}
+	loadedKey, err = loadPEMKey(&buf, pass)
 	if !reflect.DeepEqual(loadedKey, key) {
 		t.Fatalf("Got key %v, but want %v", loadedKey, key)
 	}
+
+	// Test nil passphrase.
+	if err := savePEMKey(&buf, key, pass); err != nil {
+		t.Fatalf("Failed to save ECDSA private key: %v", err)
+	}
+	if loadedKey, err = loadPEMKey(&buf, nil); loadedKey != nil || err != MissingPassphraseErr {
+		t.Fatalf("expected(nil, MissingPassphraseError), instead got (%v, %v)", loadedKey, err)
+	}
 }
 
 func TestLoadSaveIdentity(t *testing.T) {
diff --git a/tools/principal/main.go b/tools/principal/main.go
index 62a05ac..0a80da2 100644
--- a/tools/principal/main.go
+++ b/tools/principal/main.go
@@ -189,9 +189,12 @@
 			var key security.PublicKey
 			tobless, extension := args[0], args[1]
 			if finfo, err := os.Stat(tobless); err == nil && finfo.IsDir() {
-				other, _, err := vsecurity.NewPersistentPrincipal(tobless)
+				// TODO(suharshs,ashankar,ataly): How should we make an ecrypted pk... or is that up to the agent?
+				other, err := vsecurity.LoadPersistentPrincipal(tobless, nil)
 				if err != nil {
-					return fmt.Errorf("failed to read principal in directory %q: %v", tobless, err)
+					if other, err = vsecurity.CreatePersistentPrincipal(tobless, nil); err != nil {
+						return fmt.Errorf("failed to read principal in directory %q: %v", tobless, err)
+					}
 				}
 				key = other.PublicKey()
 			} else if other, err := decodeBlessings(tobless); err != nil {
@@ -363,9 +366,10 @@
 				return fmt.Errorf("requires exactly two arguments: <directory> and <blessing>, provided %d", len(args))
 			}
 			dir, name := args[0], args[1]
-			p, existed, err := vsecurity.NewPersistentPrincipal(dir)
-			if existed {
-				return fmt.Errorf("principal already exists in %q", dir)
+			// TODO(suharshs,ashankar,ataly): How should we make an ecrypted pk... or is that up to the agent?
+			p, err := vsecurity.CreatePersistentPrincipal(dir, nil)
+			if err != nil {
+				return err
 			}
 			blessings, err := p.BlessSelf(name)
 			if err != nil {