blob: 292c58e9d644cc4f82708337cb7ec0a0dca9f47f [file] [log] [blame]
Matt Rosencrantzb0cd02d2015-08-17 17:37:06 -07001// Copyright 2015 The Vanadium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package security_test
6
7import (
8 "fmt"
9 "testing"
10 "time"
11
12 "v.io/v23"
13 "v.io/v23/context"
14 "v.io/v23/rpc"
15 "v.io/v23/security"
16 securitylib "v.io/x/ref/lib/security"
17 "v.io/x/ref/lib/xrpc"
18 _ "v.io/x/ref/runtime/factories/generic"
19 "v.io/x/ref/test"
20 "v.io/x/ref/test/testutil"
21)
22
23func init() {
24 test.Init()
25}
26
27type expiryDischarger struct {
28 called bool
29}
30
31func (ed *expiryDischarger) Discharge(ctx *context.T, call rpc.StreamServerCall, cav security.Caveat, _ security.DischargeImpetus) (security.Discharge, error) {
32 tp := cav.ThirdPartyDetails()
33 if tp == nil {
34 return security.Discharge{}, fmt.Errorf("discharger: %v does not represent a third-party caveat", cav)
35 }
36 if err := tp.Dischargeable(ctx, call.Security()); err != nil {
37 return security.Discharge{}, fmt.Errorf("third-party caveat %v cannot be discharged for this context: %v", cav, err)
38 }
39 expDur := 10 * time.Millisecond
40 if ed.called {
41 expDur = time.Second
42 }
43 expiry, err := security.NewExpiryCaveat(time.Now().Add(expDur))
44 if err != nil {
45 return security.Discharge{}, fmt.Errorf("failed to create an expiration on the discharge: %v", err)
46 }
47 d, err := call.Security().LocalPrincipal().MintDischarge(cav, expiry)
48 if err != nil {
49 return security.Discharge{}, err
50 }
51 ctx.Infof("got discharge on sever %#v", d)
52 ed.called = true
53 return d, nil
54}
55
56func TestPrepareDischarges(t *testing.T) {
57 ctx, shutdown := test.V23Init()
58 defer shutdown()
59
60 pclient := testutil.NewPrincipal("client")
61 cctx, err := v23.WithPrincipal(ctx, pclient)
62 if err != nil {
63 t.Fatal(err)
64 }
65 pdischarger := testutil.NewPrincipal("discharger")
66 dctx, err := v23.WithPrincipal(ctx, pdischarger)
67 if err != nil {
68 t.Fatal(err)
69 }
70 pclient.AddToRoots(pdischarger.BlessingStore().Default())
71 pclient.AddToRoots(v23.GetPrincipal(ctx).BlessingStore().Default())
72 pdischarger.AddToRoots(pclient.BlessingStore().Default())
73 pdischarger.AddToRoots(v23.GetPrincipal(ctx).BlessingStore().Default())
74
75 expcav, err := security.NewExpiryCaveat(time.Now().Add(time.Hour))
76 if err != nil {
77 t.Fatal(err)
78 }
79 tpcav, err := security.NewPublicKeyCaveat(
80 pdischarger.PublicKey(),
81 "discharger",
82 security.ThirdPartyRequirements{},
83 expcav)
84 if err != nil {
85 t.Fatal(err)
86 }
87 cbless, err := pclient.BlessSelf("clientcaveats", tpcav)
88 if err != nil {
89 t.Fatal(err)
90 }
91 tpid := tpcav.ThirdPartyDetails().ID()
92
93 v23.GetPrincipal(dctx)
94 _, err = xrpc.NewServer(dctx,
95 "discharger",
96 &expiryDischarger{},
97 security.AllowEveryone())
98 if err != nil {
99 t.Fatal(err)
100 }
101
102 // Fetch discharges for tpcav.
103 buffer := 100 * time.Millisecond
104 discharges := securitylib.PrepareDischarges(cctx, cbless,
105 security.DischargeImpetus{}, buffer)
106 if len(discharges) != 1 {
107 t.Errorf("Got %d discharges, expected 1.", len(discharges))
108 }
109 dis, has := discharges[tpid]
110 if !has {
111 t.Errorf("Got %#v, Expected discharge for %s", discharges, tpid)
112 }
113 // Check that the discharges is not yet expired, but is expired after 100 milliseconds.
114 expiry := dis.Expiry()
115 // The discharge should expire.
116 select {
117 case <-time.After(time.Now().Sub(expiry)):
118 break
119 case <-time.After(time.Second):
120 t.Fatalf("discharge didn't expire within a second")
121 }
122
123 // Preparing Discharges again to get fresh discharges.
124 discharges = securitylib.PrepareDischarges(cctx, cbless,
125 security.DischargeImpetus{}, buffer)
126 if len(discharges) != 1 {
127 t.Errorf("Got %d discharges, expected 1.", len(discharges))
128 }
129 dis, has = discharges[tpid]
130 if !has {
131 t.Errorf("Got %#v, Expected discharge for %s", discharges, tpid)
132 }
133 now := time.Now()
134 if expiry = dis.Expiry(); expiry.Before(now) {
135 t.Fatalf("discharge has expired %v, but should be fresh", dis)
136 }
137}