Skip to content

Commit

Permalink
Catalog: use dynamic signing key
Browse files Browse the repository at this point in the history
  • Loading branch information
N-o-Z committed Jan 30, 2025
1 parent 5c4cd03 commit 2a78fe0
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 17 deletions.
12 changes: 6 additions & 6 deletions pkg/api/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ func (c *Controller) CreatePresignMultipartUpload(w http.ResponseWriter, r *http
}

// generate a new address for the object we like to upload
address, err := c.Catalog.GetAddressWithSignature(repository, branch, params.Path)
address, err := c.Catalog.GetAddressWithSignature(repo, branch, params.Path)
if err != nil {
writeError(w, r, http.StatusInternalServerError, err)
return
Expand Down Expand Up @@ -308,7 +308,7 @@ func (c *Controller) AbortPresignMultipartUpload(w http.ResponseWriter, r *http.
return
}

if err := c.Catalog.VerifyLinkAddress(repository, branch, params.Path, physicalAddress); c.handleAPIError(ctx, w, r, err) {
if err := c.Catalog.VerifyLinkAddress(repo, branch, params.Path, physicalAddress); c.handleAPIError(ctx, w, r, err) {
return
}

Expand Down Expand Up @@ -377,7 +377,7 @@ func (c *Controller) CompletePresignMultipartUpload(w http.ResponseWriter, r *ht
}

// verify it has been saved for linking
if err := c.Catalog.VerifyLinkAddress(repository, branch, params.Path, physicalAddress); c.handleAPIError(ctx, w, r, err) {
if err := c.Catalog.VerifyLinkAddress(repo, branch, params.Path, physicalAddress); c.handleAPIError(ctx, w, r, err) {
return
}

Expand Down Expand Up @@ -702,7 +702,7 @@ func (c *Controller) GetPhysicalAddress(w http.ResponseWriter, r *http.Request,
return
}

address, err := c.Catalog.GetAddressWithSignature(repository, branch, params.Path)
address, err := c.Catalog.GetAddressWithSignature(repo, branch, params.Path)
if err != nil {
writeError(w, r, http.StatusInternalServerError, err)
return
Expand Down Expand Up @@ -779,7 +779,7 @@ func (c *Controller) LinkPhysicalAddress(w http.ResponseWriter, r *http.Request,

storage := c.Config.StorageConfig().GetStorageByID(repo.StorageID)
if storage == nil {
c.handleAPIError(ctx, w, r, fmt.Errorf("no storage namespace info found for id: %s: %w", repo.StorageID, block.ErrInvalidAddress))
c.handleAPIError(ctx, w, r, fmt.Errorf("no storage config found for id: %s: %w", repo.StorageID, block.ErrInvalidAddress))
return
}
blockStoreType := storage.BlockstoreType()
Expand All @@ -802,7 +802,7 @@ func (c *Controller) LinkPhysicalAddress(w http.ResponseWriter, r *http.Request,

if addressType == catalog.AddressTypeRelative {
// if the address is in the storage namespace, verify it has been produced by lakeFS
if err = c.Catalog.VerifyLinkAddress(repository, branch, params.Path, physicalAddress); c.handleAPIError(ctx, w, r, err) {
if err = c.Catalog.VerifyLinkAddress(repo, branch, params.Path, physicalAddress); c.handleAPIError(ctx, w, r, err) {
return
}

Expand Down
30 changes: 19 additions & 11 deletions pkg/catalog/catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ type Config struct {
}

type Catalog struct {
Cfg Config
BlockAdapter block.Adapter
Store Store
walkerFactory WalkerFactory
Expand All @@ -235,7 +236,6 @@ type Catalog struct {
deleteSensor *graveler.DeleteSensor
UGCPrepareMaxFileSize int64
UGCPrepareInterval time.Duration
signingKey config.SecureString
}

const (
Expand Down Expand Up @@ -412,6 +412,7 @@ func New(ctx context.Context, cfg Config) (*Catalog, error) {
workPool := pond.New(sharedWorkers, sharedWorkers*pendingTasksPerWorker, pond.Context(ctx))

return &Catalog{
Cfg: cfg,
BlockAdapter: tierFSParams.Adapter,
Store: gStore,
UGCPrepareMaxFileSize: baseCfg.UGC.PrepareMaxFileSize,
Expand All @@ -425,8 +426,6 @@ func New(ctx context.Context, cfg Config) (*Catalog, error) {
KVStoreLimited: storeLimiter,
addressProvider: addressProvider,
deleteSensor: deleteSensor,
// TODO(niro): This should be removed - we need to return the signing key dynamically from the blockAdapter
signingKey: baseCfg.Blockstore.Signing.SecretKey,
}, nil
}

Expand Down Expand Up @@ -2845,15 +2844,15 @@ func getHashSum(value, signingKey []byte) []byte {
return h.Sum(nil)
}

func (c *Catalog) VerifyLinkAddress(repository, branch, path, physicalAddress string) error {
func (c *Catalog) VerifyLinkAddress(repo *Repository, branch, path, physicalAddress string) error {
idx := strings.LastIndex(physicalAddress, LinkAddressSigningDelimiter)
if idx < 0 {
return fmt.Errorf("address is not signed: %w", graveler.ErrLinkAddressInvalid)
}
address := physicalAddress[:idx]
signature := physicalAddress[idx+1:]

stringToVerify, err := getAddressJSON(repository, branch, path, address)
stringToVerify, err := getAddressJSON(repo.Name, branch, path, address)
if err != nil {
return fmt.Errorf("failed json encoding: %w", graveler.ErrLinkAddressInvalid)
}
Expand All @@ -2862,7 +2861,12 @@ func (c *Catalog) VerifyLinkAddress(repository, branch, path, physicalAddress st
return fmt.Errorf("malformed address signature: %s: %w", stringToVerify, graveler.ErrLinkAddressInvalid)
}

calculated := getHashSum(stringToVerify, []byte(c.signingKey))
storage := c.Cfg.Config.StorageConfig().GetStorageByID(repo.StorageID)
if storage == nil {
return fmt.Errorf("no storage config for id %s :%w", repo.StorageID, config.ErrNoStorageConfig)
}

calculated := getHashSum(stringToVerify, []byte(storage.SigningKey()))
if !hmac.Equal(calculated, decodedSig) {
return fmt.Errorf("invalid address signature: %w", block.ErrInvalidAddress)
}
Expand All @@ -2877,8 +2881,8 @@ func (c *Catalog) VerifyLinkAddress(repository, branch, path, physicalAddress st
return nil
}

func (c *Catalog) signAddress(logicalAddress []byte) string {
dataHmac := getHashSum(logicalAddress, []byte(c.signingKey))
func (c *Catalog) signAddress(logicalAddress []byte, signingKey string) string {
dataHmac := getHashSum(logicalAddress, []byte(signingKey))
return base64.RawURLEncoding.EncodeToString(dataHmac) // Using url encoding to avoid "/"
}

Expand All @@ -2896,13 +2900,17 @@ func getAddressJSON(repository, branch, path, physicalAddress string) ([]byte, e
})
}

func (c *Catalog) GetAddressWithSignature(repository, branch, path string) (string, error) {
func (c *Catalog) GetAddressWithSignature(repo *Repository, branch, path string) (string, error) {
physicalPath := c.PathProvider.NewPath()
data, err := getAddressJSON(repository, branch, path, physicalPath)
data, err := getAddressJSON(repo.Name, branch, path, physicalPath)
if err != nil {
return "", err
}
return physicalPath + LinkAddressSigningDelimiter + c.signAddress(data), nil
storage := c.Cfg.Config.StorageConfig().GetStorageByID(repo.StorageID)
if storage == nil {
return "", fmt.Errorf("no storage config for id %s :%w", repo.StorageID, config.ErrNoStorageConfig)
}
return physicalPath + LinkAddressSigningDelimiter + c.signAddress(data, storage.SigningKey()), nil
}

func (c *Catalog) Close() error {
Expand Down
5 changes: 5 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ type AdapterConfig interface {
BlockstoreAzureParams() (blockparams.Azure, error)
BlockstoreExtras() map[string]string
GetDefaultNamespacePrefix() *string
SigningKey() string
}

type Blockstore struct {
Expand Down Expand Up @@ -356,6 +357,10 @@ func (b *Blockstore) GetDefaultNamespacePrefix() *string {
return b.DefaultNamespacePrefix
}

func (b *Blockstore) SigningKey() string {
return b.Signing.SecretKey.SecureValue()
}

type Config interface {
GetBaseConfig() *BaseConfig
StorageConfig() StorageConfig
Expand Down

0 comments on commit 2a78fe0

Please sign in to comment.