1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
|
package bakery
import (
"context"
"sync"
)
// RootKeyStore defines store for macaroon root keys.
type RootKeyStore interface {
// Get returns the root key for the given id.
// If the item is not there, it returns ErrNotFound.
Get(ctx context.Context, id []byte) ([]byte, error)
// RootKey returns the root key to be used for making a new
// macaroon, and an id that can be used to look it up later with
// the Get method.
//
// Note that the root keys should remain available for as long
// as the macaroons using them are valid.
//
// Note that there is no need for it to return a new root key
// for every call - keys may be reused, although some key
// cycling is over time is advisable.
RootKey(ctx context.Context) (rootKey []byte, id []byte, err error)
}
// NewMemRootKeyStore returns an implementation of
// Store that generates a single key and always
// returns that from RootKey. The same id ("0") is always
// used.
func NewMemRootKeyStore() RootKeyStore {
return new(memRootKeyStore)
}
type memRootKeyStore struct {
mu sync.Mutex
key []byte
}
// Get implements Store.Get.
func (s *memRootKeyStore) Get(_ context.Context, id []byte) ([]byte, error) {
s.mu.Lock()
defer s.mu.Unlock()
if len(id) != 1 || id[0] != '0' || s.key == nil {
return nil, ErrNotFound
}
return s.key, nil
}
// RootKey implements Store.RootKey by always returning the same root
// key.
func (s *memRootKeyStore) RootKey(context.Context) (rootKey, id []byte, err error) {
s.mu.Lock()
defer s.mu.Unlock()
if s.key == nil {
newKey, err := randomBytes(24)
if err != nil {
return nil, nil, err
}
s.key = newKey
}
return s.key, []byte("0"), nil
}
|