macaroons: add encKeyMtx to prevent race condition

This commit is contained in:
nsa 2019-11-09 21:12:11 -05:00
parent b222b6e625
commit 1018df991f
No known key found for this signature in database
GPG Key ID: 118759E83439A9B1

@ -5,6 +5,7 @@ import (
"crypto/rand" "crypto/rand"
"fmt" "fmt"
"io" "io"
"sync"
"github.com/coreos/bbolt" "github.com/coreos/bbolt"
@ -47,7 +48,8 @@ var (
type RootKeyStorage struct { type RootKeyStorage struct {
*bbolt.DB *bbolt.DB
encKey *snacl.SecretKey encKeyMtx sync.RWMutex
encKey *snacl.SecretKey
} }
// NewRootKeyStorage creates a RootKeyStorage instance. // NewRootKeyStorage creates a RootKeyStorage instance.
@ -63,12 +65,15 @@ func NewRootKeyStorage(db *bbolt.DB) (*RootKeyStorage, error) {
} }
// Return the DB wrapped in a RootKeyStorage object. // Return the DB wrapped in a RootKeyStorage object.
return &RootKeyStorage{db, nil}, nil return &RootKeyStorage{DB: db, encKey: nil}, nil
} }
// CreateUnlock sets an encryption key if one is not already set, otherwise it // CreateUnlock sets an encryption key if one is not already set, otherwise it
// checks if the password is correct for the stored encryption key. // checks if the password is correct for the stored encryption key.
func (r *RootKeyStorage) CreateUnlock(password *[]byte) error { func (r *RootKeyStorage) CreateUnlock(password *[]byte) error {
r.encKeyMtx.Lock()
defer r.encKeyMtx.Unlock()
// Check if we've already unlocked the store; return an error if so. // Check if we've already unlocked the store; return an error if so.
if r.encKey != nil { if r.encKey != nil {
return ErrAlreadyUnlocked return ErrAlreadyUnlocked
@ -119,6 +124,9 @@ func (r *RootKeyStorage) CreateUnlock(password *[]byte) error {
// Get implements the Get method for the bakery.RootKeyStorage interface. // Get implements the Get method for the bakery.RootKeyStorage interface.
func (r *RootKeyStorage) Get(_ context.Context, id []byte) ([]byte, error) { func (r *RootKeyStorage) Get(_ context.Context, id []byte) ([]byte, error) {
r.encKeyMtx.RLock()
defer r.encKeyMtx.RUnlock()
if r.encKey == nil { if r.encKey == nil {
return nil, ErrStoreLocked return nil, ErrStoreLocked
} }
@ -150,6 +158,9 @@ func (r *RootKeyStorage) Get(_ context.Context, id []byte) ([]byte, error) {
// interface. // interface.
// TODO(aakselrod): Add support for key rotation. // TODO(aakselrod): Add support for key rotation.
func (r *RootKeyStorage) RootKey(_ context.Context) ([]byte, []byte, error) { func (r *RootKeyStorage) RootKey(_ context.Context) ([]byte, []byte, error) {
r.encKeyMtx.RLock()
defer r.encKeyMtx.RUnlock()
if r.encKey == nil { if r.encKey == nil {
return nil, nil, ErrStoreLocked return nil, nil, ErrStoreLocked
} }
@ -195,6 +206,9 @@ func (r *RootKeyStorage) RootKey(_ context.Context) ([]byte, []byte, error) {
// Close closes the underlying database and zeroes the encryption key stored // Close closes the underlying database and zeroes the encryption key stored
// in memory. // in memory.
func (r *RootKeyStorage) Close() error { func (r *RootKeyStorage) Close() error {
r.encKeyMtx.Lock()
defer r.encKeyMtx.Unlock()
if r.encKey != nil { if r.encKey != nil {
r.encKey.Zero() r.encKey.Zero()
} }