Skip to content

Commit

Permalink
function for generating 3p caveat
Browse files Browse the repository at this point in the history
  • Loading branch information
btoews committed Jan 24, 2025
1 parent cc1420d commit 5d85b20
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 23 deletions.
27 changes: 27 additions & 0 deletions bundle/bundle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,33 @@ func TestAttenuate(t *testing.T) {
assert.True(t, hasCav(toks[2]))
}

func TestAdd3P(t *testing.T) {
t.Parallel()

toks := append(macOpts{}.tokens(t), macOpts{}.tokens(t)...)
bun, err := ParseBundle(permLoc, toks.String())
assert.NoError(t, err)

cav, err := macaroon.NewCaveat3P(tpKey, tpLoc)
assert.NoError(t, err)
assert.NoError(t, bun.Attenuate(cav))
assert.Zero(t, cav.VerifierKey)

vk1 := bun.ts[0].(*UnverifiedMacaroon).UnsafeMac.UnsafeCaveats.Caveats[0].(*macaroon.Caveat3P).VerifierKey
assert.NotZero(t, vk1)

vk2 := bun.ts[1].(*UnverifiedMacaroon).UnsafeMac.UnsafeCaveats.Caveats[0].(*macaroon.Caveat3P).VerifierKey
assert.NotZero(t, vk2)

assert.NotEqual(t, vk1, vk2)

discharger := func(c []macaroon.Caveat) ([]macaroon.Caveat, error) { return nil, nil }
assert.NoError(t, bun.Discharge(tpLoc, tpKey, discharger))

_, err = bun.Verify(context.Background(), WithKey(permKID, permKey, nil))
assert.NoError(t, err)
}

func hasCaveat(c macaroon.Caveat) Predicate {
return MacaroonPredicate(func(m Macaroon) bool {
if !cavsHasCaveat(m.UnsafeCaveats().Caveats, c) {
Expand Down
27 changes: 27 additions & 0 deletions caveats.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,33 @@ type Caveat3P struct {
rn []byte `msgpack:"-"`
}

func NewCaveat3P(ka EncryptionKey, loc string, cs ...Caveat) (*Caveat3P, error) {
if len(ka) != EncryptionKeySize {
return nil, fmt.Errorf("bad key size: have %d, need %d", len(ka), EncryptionKeySize)
}

// make a new root hmac key for the 3p discharge macaroon
rn := NewSigningKey()

// make the ticket, which is consumed by the 3p service; then
// encode and encrypt it
ticket := &wireTicket{
DischargeKey: rn,
Caveats: *NewCaveatSet(cs...),
}

ticketBytes, err := encode(ticket)
if err != nil {
return nil, fmt.Errorf("encoding ticket: %w", err)
}

return &Caveat3P{
Location: loc,
Ticket: seal(ka, ticketBytes),
rn: rn,
}, nil
}

func init() { RegisterCaveatType(&Caveat3P{}) }
func (c *Caveat3P) CaveatType() CaveatType { return Cav3P }
func (c *Caveat3P) Name() string { return "3P" }
Expand Down
31 changes: 8 additions & 23 deletions macaroon.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,11 @@ func (m *Macaroon) Add(caveats ...Caveat) error {
}

if c3p, ok := caveat.(*Caveat3P); ok {
// make a copy since we have to modify it. in case the caveat is
// added to multiple macaroons
c3p := *c3p
caveat = &c3p

// encrypt RN under the tail hmac so we can recover it during verification
c3p.VerifierKey = seal(EncryptionKey(m.Tail), c3p.rn)

Expand Down Expand Up @@ -521,32 +526,12 @@ func (m *Macaroon) BindToParentMacaroon(parent *Macaroon) error {
// to use to check which caveats. The location is normally a URL. The
// authentication service has an authentication location URL.
func (m *Macaroon) Add3P(ka EncryptionKey, loc string, cs ...Caveat) error {
if len(ka) != EncryptionKeySize {
return fmt.Errorf("bad key size: have %d, need %d", len(ka), EncryptionKeySize)
}

// make a new root hmac key for the 3p discharge macaroon
rn := NewSigningKey()

// make the ticket, which is consumed by the 3p service; then
// encode and encrypt it
ticket := &wireTicket{
DischargeKey: rn,
Caveats: *NewCaveatSet(cs...),
}

ticketBytes, err := encode(ticket)
cav, err := NewCaveat3P(ka, loc, cs...)
if err != nil {
return fmt.Errorf("encoding ticket: %w", err)
return err
}

m.Add(&Caveat3P{
Location: loc,
Ticket: seal(ka, ticketBytes),
rn: rn,
})

return nil
return m.Add(cav)
}

// AllThirdPartyTickets extracts the encrypted tickets from a token's third party
Expand Down

0 comments on commit 5d85b20

Please sign in to comment.