Skip to content

Commit

Permalink
refactor(act): fix pr comments (#50)
Browse files Browse the repository at this point in the history
* refactor(act): fix pr comments

* refactor(act): fix linter errors

* refactor(act): move kvs to accesscontrol as a subpackage

* refactor(act): typo and comment fix
  • Loading branch information
bosi95 authored Jun 6, 2024
1 parent 09a876b commit d1ea594
Show file tree
Hide file tree
Showing 28 changed files with 446 additions and 394 deletions.
8 changes: 4 additions & 4 deletions cmd/bee/cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/rpc"
"github.com/ethersphere/bee/v2"
"github.com/ethersphere/bee/v2/pkg/accesscontrol"
chaincfg "github.com/ethersphere/bee/v2/pkg/config"
"github.com/ethersphere/bee/v2/pkg/crypto"
"github.com/ethersphere/bee/v2/pkg/crypto/clef"
"github.com/ethersphere/bee/v2/pkg/dynamicaccess"
"github.com/ethersphere/bee/v2/pkg/keystore"
filekeystore "github.com/ethersphere/bee/v2/pkg/keystore/file"
memkeystore "github.com/ethersphere/bee/v2/pkg/keystore/mem"
Expand Down Expand Up @@ -374,7 +374,7 @@ type signerConfig struct {
publicKey *ecdsa.PublicKey
libp2pPrivateKey *ecdsa.PrivateKey
pssPrivateKey *ecdsa.PrivateKey
session dynamicaccess.Session
session accesscontrol.Session
}

func waitForClef(logger log.Logger, maxRetries uint64, endpoint string) (externalSigner *external.ExternalSigner, err error) {
Expand Down Expand Up @@ -405,7 +405,7 @@ func (c *command) configureSigner(cmd *cobra.Command, logger log.Logger) (config
var signer crypto.Signer
var password string
var publicKey *ecdsa.PublicKey
var session dynamicaccess.Session
var session accesscontrol.Session
if p := c.config.GetString(optionNamePassword); p != "" {
password = p
} else if pf := c.config.GetString(optionNamePasswordFile); pf != "" {
Expand Down Expand Up @@ -478,7 +478,7 @@ func (c *command) configureSigner(cmd *cobra.Command, logger log.Logger) (config
}
signer = crypto.NewDefaultSigner(swarmPrivateKey)
publicKey = &swarmPrivateKey.PublicKey
session = dynamicaccess.NewDefaultSession(swarmPrivateKey)
session = accesscontrol.NewDefaultSession(swarmPrivateKey)
}

logger.Info("swarm public key", "public_key", hex.EncodeToString(crypto.EncodeSecp256k1PublicKey(publicKey)))
Expand Down
63 changes: 30 additions & 33 deletions pkg/dynamicaccess/accesslogic.go → pkg/accesscontrol/access.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package dynamicaccess
package accesscontrol

import (
"context"
"crypto/ecdsa"
"fmt"

"github.com/ethersphere/bee/v2/pkg/accesscontrol/kvs"
"github.com/ethersphere/bee/v2/pkg/encryption"
"github.com/ethersphere/bee/v2/pkg/kvs"
"github.com/ethersphere/bee/v2/pkg/swarm"
"golang.org/x/crypto/sha3"
)
Expand All @@ -24,27 +24,28 @@ var (

// Decryptor is a read-only interface for the ACT.
type Decryptor interface {
// DecryptRef will return a decrypted reference, for given encrypted reference and grantee
// DecryptRef will return a decrypted reference, for given encrypted reference and grantee.
DecryptRef(ctx context.Context, storage kvs.KeyValueStore, encryptedRef swarm.Address, publisher *ecdsa.PublicKey) (swarm.Address, error)
Session
}

// Control interface for the ACT (does write operations).
type Control interface {
Decryptor
// AddGrantee adds a new grantee to the ACT
// AddGrantee adds a new grantee to the ACT.
AddGrantee(ctx context.Context, storage kvs.KeyValueStore, publisherPubKey, granteePubKey *ecdsa.PublicKey) error
// EncryptRef encrypts a Swarm reference for a given grantee
// EncryptRef encrypts a Swarm reference for a given grantee.
EncryptRef(ctx context.Context, storage kvs.KeyValueStore, grantee *ecdsa.PublicKey, ref swarm.Address) (swarm.Address, error)
}

// ActLogic represents the access control logic.
type ActLogic struct {
Session
}

var _ Control = (*ActLogic)(nil)

// EncryptRef encrypts a SWARM reference for a publisher.
// EncryptRef encrypts a Swarm reference for a publisher.
func (al ActLogic) EncryptRef(ctx context.Context, storage kvs.KeyValueStore, publisherPubKey *ecdsa.PublicKey, ref swarm.Address) (swarm.Address, error) {
accessKey, err := al.getAccessKey(ctx, storage, publisherPubKey)
if err != nil {
Expand All @@ -66,32 +67,36 @@ func (al ActLogic) AddGrantee(ctx context.Context, storage kvs.KeyValueStore, pu
err error
)

// Create new access key because grantee is the publisher
// Create new access key because grantee is the publisher.
if publisherPubKey.Equal(granteePubKey) {
accessKey = encryption.GenerateRandomKey(encryption.KeyLength)
} else {
// Get previously generated access key
// Get previously generated access key.
accessKey, err = al.getAccessKey(ctx, storage, publisherPubKey)
if err != nil {
return err
}
}

// Encrypt the access key for the new Grantee
lookupKey, accessKeyDecryptionKey, err := al.getKeys(granteePubKey)
if err != nil {
return err
}

// Encrypt the access key for the new Grantee
// Encrypt the access key for the new Grantee.
cipher := encryption.New(encryption.Key(accessKeyDecryptionKey), 0, uint32(0), hashFunc)
granteeEncryptedAccessKey, err := cipher.Encrypt(accessKey)
if err != nil {
return fmt.Errorf("failed to encrypt access key: %w", err)
}

// Add the new encrypted access key to the Act
return storage.Put(ctx, lookupKey, granteeEncryptedAccessKey)
// Add the new encrypted access key to the Act.
err = storage.Put(ctx, lookupKey, granteeEncryptedAccessKey)
if err != nil {
return fmt.Errorf("failed to put value to KVS: %w", err)
}

return nil
}

// Will return the access key for a publisher (public key).
Expand All @@ -100,56 +105,48 @@ func (al *ActLogic) getAccessKey(ctx context.Context, storage kvs.KeyValueStore,
if err != nil {
return nil, err
}
// no need for constructor call if value not found in act
// no need for constructor call if value not found in act.
accessKeyDecryptionCipher := encryption.New(encryption.Key(publisherAKDecryptionKey), 0, uint32(0), hashFunc)
encryptedAK, err := storage.Get(ctx, publisherLookupKey)
if err != nil {
return nil, fmt.Errorf("failed go get value from KVS: %w", err)
}

return accessKeyDecryptionCipher.Decrypt(encryptedAK)
accessKey, err := accessKeyDecryptionCipher.Decrypt(encryptedAK)
if err != nil {
return nil, fmt.Errorf("failed to decrypt access key: %w", err)
}

return accessKey, nil
}

// Generate lookup key and access key decryption key for a given public key
// Generate lookup key and access key decryption key for a given public key.
func (al *ActLogic) getKeys(publicKey *ecdsa.PublicKey) ([]byte, []byte, error) {
nonces := [][]byte{zeroByteArray, oneByteArray}
keys, err := al.Session.Key(publicKey, nonces)
if keys == nil {
if len(keys) != len(nonces) {
return nil, nil, err
}
return keys[0], keys[1], err
}

// DecryptRef will return a decrypted reference, for given encrypted reference and publisher
// DecryptRef will return a decrypted reference, for given encrypted reference and publisher.
func (al ActLogic) DecryptRef(ctx context.Context, storage kvs.KeyValueStore, encryptedRef swarm.Address, publisher *ecdsa.PublicKey) (swarm.Address, error) {
lookupKey, accessKeyDecryptionKey, err := al.getKeys(publisher)
if err != nil {
return swarm.ZeroAddress, err
}

// Lookup encrypted access key from the ACT manifest
encryptedAccessKey, err := storage.Get(ctx, lookupKey)
if err != nil {
return swarm.ZeroAddress, fmt.Errorf("failed to get access key from KVS: %w", err)
}

// Decrypt access key
accessKeyCipher := encryption.New(encryption.Key(accessKeyDecryptionKey), 0, uint32(0), hashFunc)
accessKey, err := accessKeyCipher.Decrypt(encryptedAccessKey)
accessKey, err := al.getAccessKey(ctx, storage, publisher)
if err != nil {
return swarm.ZeroAddress, err
}

// Decrypt reference
refCipher := encryption.New(accessKey, 0, uint32(0), hashFunc)
ref, err := refCipher.Decrypt(encryptedRef.Bytes())
if err != nil {
return swarm.ZeroAddress, err
return swarm.ZeroAddress, fmt.Errorf("failed to decrypt reference: %w", err)
}

return swarm.NewAddress(ref), nil
}

// NewLogic creates a new ACT Logic from a session.
func NewLogic(s Session) ActLogic {
return ActLogic{
Session: s,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package dynamicaccess_test
package accesscontrol_test

import (
"context"
Expand All @@ -12,18 +12,18 @@ import (
"encoding/hex"
"testing"

"github.com/ethersphere/bee/v2/pkg/accesscontrol"
kvsmock "github.com/ethersphere/bee/v2/pkg/accesscontrol/kvs/mock"
"github.com/ethersphere/bee/v2/pkg/crypto"
"github.com/ethersphere/bee/v2/pkg/dynamicaccess"
kvsmock "github.com/ethersphere/bee/v2/pkg/kvs/mock"
"github.com/ethersphere/bee/v2/pkg/swarm"
"github.com/stretchr/testify/assert"
)

// Generates a new test environment with a fix private key
func setupAccessLogic() dynamicaccess.ActLogic {
// Generates a new test environment with a fix private key.
func setupAccessLogic() accesscontrol.ActLogic {
privateKey := getPrivKey(1)
diffieHellman := dynamicaccess.NewDefaultSession(privateKey)
al := dynamicaccess.NewLogic(diffieHellman)
diffieHellman := accesscontrol.NewDefaultSession(privateKey)
al := accesscontrol.NewLogic(diffieHellman)

return al
}
Expand Down Expand Up @@ -87,8 +87,8 @@ func TestDecryptRefWithGrantee_Success(t *testing.T) {
t.Parallel()
ctx := context.Background()
id0, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
diffieHellman := dynamicaccess.NewDefaultSession(id0)
al := dynamicaccess.NewLogic(diffieHellman)
diffieHellman := accesscontrol.NewDefaultSession(id0)
al := accesscontrol.NewLogic(diffieHellman)

s := kvsmock.New()
err := al.AddGrantee(ctx, s, &id0.PublicKey, &id0.PublicKey)
Expand All @@ -111,8 +111,8 @@ func TestDecryptRefWithGrantee_Success(t *testing.T) {
t.Fatalf("There was an error while calling EncryptRef: %v", err)
}

diffieHellman2 := dynamicaccess.NewDefaultSession(id1)
granteeAccessLogic := dynamicaccess.NewLogic(diffieHellman2)
diffieHellman2 := accesscontrol.NewDefaultSession(id1)
granteeAccessLogic := accesscontrol.NewLogic(diffieHellman2)
actualRef, err := granteeAccessLogic.DecryptRef(ctx, s, encryptedRef, &id0.PublicKey)
if err != nil {
t.Fatalf("There was an error while calling Get: %v", err)
Expand All @@ -139,8 +139,7 @@ func TestDecryptRef_Error(t *testing.T) {

r, err := al.DecryptRef(ctx, s, encryptedRef, nil)
if err == nil {
t.Logf("r: %s", r.String())
t.Fatalf("Get should return encrypted access key not found error!")
t.Fatalf("Get should return error but got reference: %v", r)
}
}

Expand Down Expand Up @@ -168,9 +167,6 @@ func TestAddPublisher(t *testing.T) {
if len(decodedEncryptedAccessKey) != 64 {
t.Fatalf("AddGrantee: expected encrypted access key length 64, got %d", len(decodedEncryptedAccessKey))
}
if s == nil {
t.Fatalf("AddGrantee: expected act, got nil")
}
}

func TestAddNewGranteeToContent(t *testing.T) {
Expand Down
Loading

0 comments on commit d1ea594

Please sign in to comment.