Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(act): fix pr comments #50

Merged
merged 4 commits into from
Jun 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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