cmd/principal: addtoroots can now be used to add (key, blessingpattern)
pairs directly (without a blessing).
I intend to use this in the prod-services test, where I will fetch
the public key via HTTP and then add to the roots of programs used
to talk to production services.
Change-Id: I49563b22ac8912f692a5929015f039f5c0062b54
diff --git a/cmd/principal/doc.go b/cmd/principal/doc.go
index fc65e1b..5385f29 100644
--- a/cmd/principal/doc.go
+++ b/cmd/principal/doc.go
@@ -26,7 +26,8 @@
blessself Generate a self-signed blessing
bless Bless another principal
store Manipulate and inspect the principal's blessing store
- addtoroots Add provided blessings to root set
+ addtoroots Add to the set of identity providers recognized by this
+ principal
help Display help for commands or topics
Run "principal help [command]" for command usage.
@@ -378,22 +379,31 @@
Principal Addtoroots
-Adds the provided blessings to the set of trusted roots for this principal.
+Adds an identity provider to the set of recognized roots public keys for this
+principal.
-'addtoroots b' adds blessings b to the trusted root set.
+It accepts either a single argument (which points to a file containing a
+blessing) or two arguments (a name and a base64-encoded DER-encoded public key).
-For example, to make the principal in credentials directory A trust the root of
-the default blessing in credentials directory B:
+For example, to make the principal in credentials directory A recognize the root
+of the default blessing in credentials directory B:
principal -veyron.credentials=B bless A some_extension |
principal -veyron.credentials=A addtoroots -
-
The extension 'some_extension' has no effect in the command above.
-Usage:
- principal addtoroots <file>
+Or to make the principal in credentials director A recognize the base64-encoded
+public key KEY for blessing patterns P:
+ principal -veyron.credentials=A addtoroots KEY P
-<file> is the path to a file containing a blessing typically obtained from this
-tool. - is used for STDIN.
+Usage:
+ principal addtoroots <key|blessing> [<blessing pattern>]
+
+<blessing> is the path to a file containing a blessing typically obtained from
+this tool. - is used for STDIN.
+
+<key> is a base64-encoded, DER-encoded public key.
+
+<blessing pattern> is the blessing pattern for which <key> should be recognized.
Principal Help
diff --git a/cmd/principal/main.go b/cmd/principal/main.go
index 0a79e3b..8cf43f4 100644
--- a/cmd/principal/main.go
+++ b/cmd/principal/main.go
@@ -365,41 +365,60 @@
cmdAddToRoots = &cmdline.Command{
Name: "addtoroots",
- Short: "Add provided blessings to root set",
+ Short: "Add to the set of identity providers recognized by this principal",
Long: `
-Adds the provided blessings to the set of trusted roots for this principal.
+Adds an identity provider to the set of recognized roots public keys for this principal.
-'addtoroots b' adds blessings b to the trusted root set.
+It accepts either a single argument (which points to a file containing a blessing)
+or two arguments (a name and a base64-encoded DER-encoded public key).
-For example, to make the principal in credentials directory A trust the
+For example, to make the principal in credentials directory A recognize the
root of the default blessing in credentials directory B:
principal -veyron.credentials=B bless A some_extension |
principal -veyron.credentials=A addtoroots -
-
The extension 'some_extension' has no effect in the command above.
+
+Or to make the principal in credentials director A recognize the base64-encoded
+public key KEY for blessing patterns P:
+ principal -veyron.credentials=A addtoroots KEY P
`,
- ArgsName: "<file>",
+ ArgsName: "<key|blessing> [<blessing pattern>]",
ArgsLong: `
-<file> is the path to a file containing a blessing typically obtained
-from this tool. - is used for STDIN.
+<blessing> is the path to a file containing a blessing typically obtained from
+this tool. - is used for STDIN.
+
+<key> is a base64-encoded, DER-encoded public key.
+
+<blessing pattern> is the blessing pattern for which <key> should be recognized.
`,
Run: func(cmd *cmdline.Command, args []string) error {
- if len(args) != 1 {
- return fmt.Errorf("requires exactly one argument <file>, provided %d", len(args))
+ if len(args) != 1 && len(args) != 2 {
+ return fmt.Errorf("requires either one argument <file>, or two arguments <key> <blessing pattern>, provided %d", len(args))
}
- blessings, err := decodeBlessings(args[0])
- if err != nil {
- return fmt.Errorf("failed to decode provided blessings: %v", err)
- }
-
ctx, shutdown := v23.Init()
defer shutdown()
p := v23.GetPrincipal(ctx)
- if err := p.AddToRoots(blessings); err != nil {
- return fmt.Errorf("AddToRoots failed: %v", err)
+ if len(args) == 1 {
+ blessings, err := decodeBlessings(args[0])
+ if err != nil {
+ return fmt.Errorf("failed to decode provided blessings: %v", err)
+ }
+ if err := p.AddToRoots(blessings); err != nil {
+ return fmt.Errorf("AddToRoots failed: %v", err)
+ }
+ return nil
}
- return nil
+ // len(args) == 2
+ der, err := base64.URLEncoding.DecodeString(args[0])
+ if err != nil {
+ return fmt.Errorf("invalid base64 encoding of public key: %v", err)
+ }
+ key, err := security.UnmarshalPublicKey(der)
+ if err != nil {
+ return fmt.Errorf("invalid DER encoding of public key: %v", err)
+ }
+ return p.Roots().Add(key, security.BlessingPattern(args[1]))
},
}
diff --git a/cmd/principal/principal_v23_test.go b/cmd/principal/principal_v23_test.go
index 5f4b522..ac7ff5d 100644
--- a/cmd/principal/principal_v23_test.go
+++ b/cmd/principal/principal_v23_test.go
@@ -475,7 +475,7 @@
}
}
-func V23TestAddToRoots(t *v23tests.T) {
+func V23TestAddBlessingsToRoots(t *v23tests.T) {
var (
bin = t.BuildGoPkg("v.io/x/ref/cmd/principal")
aliceDir = t.NewTempDir()
@@ -519,6 +519,32 @@
}
}
+func V23TestAddKeyToRoots(t *v23tests.T) {
+ var (
+ bin = t.BuildGoPkg("v.io/x/ref/cmd/principal")
+ aliceDir = t.NewTempDir()
+ )
+ bin.Start("create", aliceDir, "alice").WaitOrDie(os.Stdout, os.Stderr)
+ // The second argument and the "want" line below were generated by:
+ // import "encoding/base64"
+ // import "v.io/x/ref/security"
+ //
+ // key, _, _ := security.NewPrincipalKey()
+ // der, _ := key.MarshalBinary()
+ // b64 := base64.URLEncoding.EncodeToString(der) // argument to addtoroots
+ // str := fmt.Sprintf("%v", key) // for the "want" line
+ bin.Start("--veyron.credentials="+aliceDir, "addtoroots", "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE9iRjaFDoGJI9tarUwWqIW31ti72krThkYByn1v9Lf89D9VA0Mg2oUL7FDDM7qxjZcVM1ktM_W4tBfMVuRZmVCA==", "some_other_provider").WaitOrDie(os.Stdout, os.Stderr)
+ // "foo" should appear in the set of BlessingRoots
+ output := bin.Start("--veyron.credentials="+aliceDir, "dump").Output()
+ want := fmt.Sprintf("41:26:f6:aa:54:f9:31:d4:9d:1f:d2:69:c6:c5:50:70 : [some_other_provider]")
+ for _, line := range strings.Split(output, "\n") {
+ if line == want {
+ return
+ }
+ }
+ t.Errorf("Could not find line:\n%v\nin output:\n%v\n", want, output)
+}
+
func credEnv(dir string) string {
return fmt.Sprintf("%s=%s", envvar.Credentials, dir)
}
diff --git a/cmd/principal/v23_test.go b/cmd/principal/v23_test.go
index b2a9bb3..c0d9525 100644
--- a/cmd/principal/v23_test.go
+++ b/cmd/principal/v23_test.go
@@ -60,6 +60,10 @@
v23tests.RunTest(t, V23TestBless)
}
-func TestV23AddToRoots(t *testing.T) {
- v23tests.RunTest(t, V23TestAddToRoots)
+func TestV23AddBlessingsToRoots(t *testing.T) {
+ v23tests.RunTest(t, V23TestAddBlessingsToRoots)
+}
+
+func TestV23AddKeyToRoots(t *testing.T) {
+ v23tests.RunTest(t, V23TestAddKeyToRoots)
}