blob: 1f2758014cc8f643cc301d8a036869f37a3dd4f5 [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"fmt"
"os"
"reflect"
"runtime"
"v.io/v23"
"v.io/v23/security"
"v.io/x/ref/envvar"
_ "v.io/x/ref/profiles"
)
func newKey() security.PublicKey {
k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
panic(err)
}
return security.NewECDSAPublicKey(&k.PublicKey)
}
func main() {
var errors []string
defer func() {
if len(errors) == 0 {
return
}
// Print out all errors and exit with failure.
for _, e := range errors {
fmt.Fprintln(os.Stderr, e)
}
os.Exit(1)
}()
errorf := func(format string, args ...interface{}) {
_, file, line, _ := runtime.Caller(1)
errors = append(errors, fmt.Sprintf("%v:%d: %v", file, line, fmt.Sprintf(format, args...)))
}
ctx, shutdown := v23.Init()
defer shutdown()
p := v23.GetPrincipal(ctx)
// Make sure we're running under a pristine agent to begin with.
// The agent aims to be transparent, so use a collection of heuristics
// to detect this.
if got := os.Getenv(envvar.Credentials); len(got) != 0 {
errorf("%v environment variable is unexpectedly set", envvar.Credentials)
}
if got := os.Getenv(envvar.AgentEndpoint); len(got) == 0 {
errorf("%v environment variable is not set", envvar.AgentEndpoint)
}
// A pristine agent has a single blessing "agent_principal" (from agentd/main.go).
if blessings := p.BlessingsInfo(p.BlessingStore().Default()); len(blessings) != 1 {
errorf("Got %d blessings, expected 1: %v", len(blessings), blessings)
} else if _, ok := blessings["agent_principal"]; !ok {
errorf("No agent_principal blessins, got %v", blessings)
}
// BlessSelf
b, err := p.BlessSelf("batman")
if err != nil {
errorf("BlessSelf: %v", err)
}
// Bless
if _, err := p.Bless(newKey(), b, "delegate", security.UnconstrainedUse()); err != nil {
errorf("Bless: %v", err)
}
// Sign & PublicKey
signature, err := p.Sign([]byte("bugs bunny"))
if err != nil {
errorf("Sign: %v", err)
}
if !signature.Verify(p.PublicKey(), []byte("bugs bunny")) {
errorf("signature.Verify: %v", err)
}
// MintDischarge
cav, err := security.NewMethodCaveat("method")
if err != nil {
errorf("security.MethodCaveat: %v", err)
}
tpcav, err := security.NewPublicKeyCaveat(p.PublicKey(), "location", security.ThirdPartyRequirements{}, cav)
if err != nil {
errorf("security.NewPublicKeyCaveat: %v", err)
}
if _, err := p.MintDischarge(tpcav, cav); err != nil {
errorf("MintDischarge: %v", err)
}
// BlessingRoots
if err := p.Roots().Recognized(p.PublicKey(), "batman"); err == nil {
errorf("Roots().Recognized returned nil")
}
if err := p.AddToRoots(b); err != nil {
errorf("AddToRoots: %v", err)
}
if err := p.Roots().Recognized(p.PublicKey(), "batman"); err != nil {
errorf("Roots().Recognized: %v", err)
}
// BlessingStore: Defaults
if err := p.BlessingStore().SetDefault(security.Blessings{}); err != nil {
errorf("BlessingStore().SetDefault: %v", err)
}
if def := p.BlessingStore().Default(); !def.IsZero() {
errorf("BlessingStore().Default returned %v, want empty", def)
}
if err := p.BlessingStore().SetDefault(b); err != nil {
errorf("BlessingStore().SetDefault: %v", err)
}
if def := p.BlessingStore().Default(); !reflect.DeepEqual(def, b) {
errorf("BlessingStore().Default returned [%v], want [%v]", def, b)
}
// BlessingStore: Set & ForPeer
// First, clear out the self-generated default of the blessing store.
if _, err := p.BlessingStore().Set(security.Blessings{}, security.AllPrincipals); err != nil {
errorf("BlessingStore().Set(nil, %q): %v", security.AllPrincipals, err)
}
if forpeer := p.BlessingStore().ForPeer("superman/friend"); !forpeer.IsZero() {
errorf("BlessingStore().ForPeer unexpectedly returned %v", forpeer)
}
if old, err := p.BlessingStore().Set(b, "superman"); err != nil {
errorf("BlessingStore().Set returned (%v, %v)", old, err)
}
if forpeer := p.BlessingStore().ForPeer("superman/friend"); !reflect.DeepEqual(forpeer, b) {
errorf("BlessingStore().ForPeer returned %v and not %v", forpeer, b)
}
}