"x/ref": SeekBlessings also sends public key of the principal tool
Currently the 'seekblessings' flow involves obtaining a macaroon
from the HTTPS identity service and sending that macaroon over a
Vanadium RPC in order to obtain a blessing. The returned blessing
is based on the email address encapsulated in the macaroon.
At the momement, the macaroon is a bearer credential and can be used
(to obtain a blessing) by anyone who holds it. This makes it an
attractive target for theft.
We plan to bind the macaroon to the public key of the principal
tool so that only the principal tool can use the macaroon to
obtain a blessing.
This would be accomplished in two steps:
1) The principal tool will be updated to also send its public
key in the HTTPS request to 'auth/google' endpoint of the Identity
Service.
2) The Identity service will be updated to include the public key
received from the tool in the issued macaroon, and only grant blessings
to clients whose public key matches the public key in the macaroon
presented by them
This CL carries out Step 1.
Change-Id: Ieb943abc5574a8a6f079b4c6676f42acf3f7f330
diff --git a/cmd/principal/bless.go b/cmd/principal/bless.go
index 3ed3ed9..80db361 100644
--- a/cmd/principal/bless.go
+++ b/cmd/principal/bless.go
@@ -59,7 +59,7 @@
return service, macaroon, root, nil
}
-func getMacaroonForBlessRPC(blessServerURL string, blessedChan <-chan string, browser bool) (<-chan string, error) {
+func getMacaroonForBlessRPC(key security.PublicKey, blessServerURL string, blessedChan <-chan string, browser bool) (<-chan string, error) {
// Setup a HTTP server to recieve a blessing macaroon from the identity server.
// Steps:
// 1. Generate a state token to be included in the HTTP request
@@ -118,7 +118,7 @@
go http.Serve(ln, nil)
// Print the link to start the flow.
- url, err := seekBlessingsURL(blessServerURL, redirectURL, state)
+ url, err := seekBlessingsURL(key, blessServerURL, redirectURL, state)
if err != nil {
return nil, fmt.Errorf("failed to create seekBlessingsURL: %s", err)
}
@@ -135,14 +135,19 @@
return result, nil
}
-func seekBlessingsURL(blessServerURL, redirectURL, state string) (string, error) {
+func seekBlessingsURL(key security.PublicKey, blessServerURL, redirectURL, state string) (string, error) {
baseURL, err := url.Parse(joinURL(blessServerURL, identity.SeekBlessingsRoute))
if err != nil {
return "", fmt.Errorf("failed to parse url: %v", err)
}
+ keyBytes, err := key.MarshalBinary()
+ if err != nil {
+ return "", fmt.Errorf("failed to marshal public key: %v", err)
+ }
params := url.Values{}
params.Add("redirect_url", redirectURL)
params.Add("state", state)
+ params.Add("public_key", base64.URLEncoding.EncodeToString(keyBytes))
baseURL.RawQuery = params.Encode()
return baseURL.String(), nil
}
diff --git a/cmd/principal/main.go b/cmd/principal/main.go
index 2c76e3a..dc95990 100644
--- a/cmd/principal/main.go
+++ b/cmd/principal/main.go
@@ -691,9 +691,11 @@
ctx, shutdown := v23.Init()
defer shutdown()
+ p := v23.GetPrincipal(ctx)
+
blessedChan := make(chan string)
defer close(blessedChan)
- macaroonChan, err := getMacaroonForBlessRPC(flagSeekBlessingsFrom, blessedChan, flagSeekBlessingsBrowser)
+ macaroonChan, err := getMacaroonForBlessRPC(p.PublicKey(), flagSeekBlessingsFrom, blessedChan, flagSeekBlessingsBrowser)
if err != nil {
return fmt.Errorf("failed to get macaroon from Vanadium blesser: %v", err)
}
@@ -706,8 +708,6 @@
// Wait for getTokenForBlessRPC to clean up:
<-macaroonChan
- p := v23.GetPrincipal(ctx)
-
if flagSeekBlessingsSetDefault {
if err := p.BlessingStore().SetDefault(blessings); err != nil {
return fmt.Errorf("failed to set blessings %v as default: %v", blessings, err)