-
Notifications
You must be signed in to change notification settings - Fork 186
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
Disperser auth #984
Open
cody-littley
wants to merge
58
commits into
Layr-Labs:master
Choose a base branch
from
cody-littley:disperser-auth
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Disperser auth #984
Changes from all commits
Commits
Show all changes
58 commits
Select commit
Hold shift + click to select a range
0936f5f
Enable TLS connections between the disperser and the DA nodes.
cody-littley d36424e
Incremental progress.
cody-littley 342d500
Moar cowsay
cody-littley fd2ab69
formatting
cody-littley e2e3fef
Started working on unit test.
cody-littley 4373095
Incremental progress.
cody-littley df38980
It works now, kind of
cody-littley d54c7f7
Incremental progress.
cody-littley 083d67d
Start experimenting with ecdsa.
cody-littley 0a5c91a
Authorize StoreChunks() requests.
cody-littley 8e9c16b
Merge branch 'master' into disperser-auth
cody-littley f348550
Update docs.
cody-littley 01b7ece
Incremental progress.
cody-littley e09a77c
Incremental progress.
cody-littley 290c93c
Incremental progress.
cody-littley 5ba4b7b
Incremental progress.
cody-littley e094371
Added test placeholder.
cody-littley db0885a
shuffle stuff around
cody-littley da2ca6c
Merge branch 'master' into disperser-auth
cody-littley b04fcfa
Unit tests for request signing.
cody-littley 29e7e7d
Delete stale code.
cody-littley fb1ebfb
Get things kind of working
cody-littley 6ca7c9b
Finished unit tests.
cody-littley 3348883
Cleanup.
cody-littley e5966f0
Cleanup
cody-littley f28a5d4
Merge branch 'master' into disperser-auth
cody-littley f0c6f4e
Cleanup.
cody-littley 6a00256
Added request signer.
cody-littley 27d5b8a
Incremental progress.
cody-littley bbd82ec
Update flags.
cody-littley 157c2ea
Started work on unit test, not yet working.
cody-littley d793501
Incremental progress in kludging something together
cody-littley b81e430
Incremental test iteration.
cody-littley 7327db1
Added debug printing.
cody-littley 8cfa971
IT'S ALIVE!
cody-littley 306746e
Partial cleanup.
cody-littley b41d729
Move code to proper locations.
cody-littley d709520
Copy eigensdk-go implementation of kms parsing.
cody-littley 2e44b02
Update kms.go
anupsv aebda81
Create kms_fuzz_test.go
anupsv 260bf79
Update Makefile for fuzz tests
anupsv dbd0d24
Merge pull request #1 from anupsv/disperser-auth
cody-littley 5dbb178
Merge branch 'master' into disperser-auth
cody-littley dcd3e06
Disable request signing if KMS key name is not provided.
cody-littley 11cf45a
Merge branch 'master' into disperser-auth
cody-littley 3580bed
Merge branch 'master' into disperser-auth
cody-littley f6b008f
Tie into bindings.
cody-littley 1493ded
Incremental progress.
cody-littley feab7a1
Merge branch 'master' into disperser-auth
cody-littley 52f2354
Add debug code.
cody-littley 7c5cc93
Fix unit test.
cody-littley c83db79
Disable request signing for inabox e2e test.
cody-littley e5cb69c
Added flag for disabling signing.
cody-littley 20216c4
Cleanup.
cody-littley 3c325ef
Made suggested changes.
cody-littley 02ed38a
tweak docker build
cody-littley 80c7e6d
Make requested changes.
cody-littley 2b6cbb2
Made suggested changes.
cody-littley File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package mock | ||
|
||
import ( | ||
"context" | ||
"crypto/ecdsa" | ||
"github.com/Layr-Labs/eigenda/api/clients/v2" | ||
v2 "github.com/Layr-Labs/eigenda/api/grpc/node/v2" | ||
"github.com/Layr-Labs/eigenda/node/auth" | ||
) | ||
|
||
var _ clients.DispersalRequestSigner = &staticRequestSigner{} | ||
|
||
// StaticRequestSigner is a DispersalRequestSigner that signs requests with a static key (i.e. it doesn't use AWS KMS). | ||
// Useful for testing. | ||
type staticRequestSigner struct { | ||
key *ecdsa.PrivateKey | ||
} | ||
|
||
func NewStaticRequestSigner(key *ecdsa.PrivateKey) clients.DispersalRequestSigner { | ||
return &staticRequestSigner{ | ||
key: key, | ||
} | ||
} | ||
|
||
func (s *staticRequestSigner) SignStoreChunksRequest( | ||
ctx context.Context, | ||
request *v2.StoreChunksRequest) ([]byte, error) { | ||
|
||
return auth.SignStoreChunksRequest(s.key, request) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package clients | ||
|
||
import ( | ||
"context" | ||
"crypto/ecdsa" | ||
"fmt" | ||
grpc "github.com/Layr-Labs/eigenda/api/grpc/node/v2" | ||
"github.com/Layr-Labs/eigenda/api/hashing" | ||
"github.com/Layr-Labs/eigenda/common" | ||
"github.com/aws/aws-sdk-go-v2/aws" | ||
"github.com/aws/aws-sdk-go-v2/service/kms" | ||
) | ||
|
||
// DispersalRequestSigner encapsulates the logic for signing GetChunks requests. | ||
type DispersalRequestSigner interface { | ||
// SignStoreChunksRequest signs a StoreChunksRequest. Does not modify the request | ||
// (i.e. it does not insert the signature). | ||
SignStoreChunksRequest(ctx context.Context, request *grpc.StoreChunksRequest) ([]byte, error) | ||
} | ||
|
||
var _ DispersalRequestSigner = &requestSigner{} | ||
|
||
type requestSigner struct { | ||
keyID string | ||
publicKey *ecdsa.PublicKey | ||
keyManager *kms.Client | ||
} | ||
|
||
// NewDispersalRequestSigner creates a new DispersalRequestSigner. | ||
func NewDispersalRequestSigner( | ||
ctx context.Context, | ||
region string, | ||
endpoint string, | ||
keyID string) (DispersalRequestSigner, error) { | ||
|
||
keyManager := kms.New(kms.Options{ | ||
Region: region, | ||
BaseEndpoint: aws.String(endpoint), | ||
}) | ||
|
||
key, err := common.LoadPublicKeyKMS(ctx, keyManager, keyID) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to get ecdsa public key: %w", err) | ||
} | ||
|
||
return &requestSigner{ | ||
keyID: keyID, | ||
publicKey: key, | ||
keyManager: keyManager, | ||
}, nil | ||
} | ||
|
||
func (s *requestSigner) SignStoreChunksRequest(ctx context.Context, request *grpc.StoreChunksRequest) ([]byte, error) { | ||
hash := hashing.HashStoreChunksRequest(request) | ||
|
||
signature, err := common.SignKMS(ctx, s.keyManager, s.keyID, s.publicKey, hash) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to sign request: %w", err) | ||
} | ||
|
||
return signature, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
package clients | ||
|
||
import ( | ||
"context" | ||
"github.com/Layr-Labs/eigenda/common" | ||
"github.com/Layr-Labs/eigenda/common/testutils/random" | ||
"github.com/Layr-Labs/eigenda/inabox/deploy" | ||
"github.com/Layr-Labs/eigenda/node/auth" | ||
"github.com/aws/aws-sdk-go-v2/aws" | ||
"github.com/aws/aws-sdk-go-v2/service/kms" | ||
"github.com/aws/aws-sdk-go-v2/service/kms/types" | ||
"github.com/ethereum/go-ethereum/crypto" | ||
"github.com/ory/dockertest/v3" | ||
"github.com/stretchr/testify/require" | ||
"log" | ||
"os" | ||
"path/filepath" | ||
"runtime" | ||
"testing" | ||
) | ||
|
||
var ( | ||
dockertestPool *dockertest.Pool | ||
dockertestResource *dockertest.Resource | ||
) | ||
|
||
const ( | ||
localstackPort = "4570" | ||
localstackHost = "http://0.0.0.0:4570" | ||
region = "us-east-1" | ||
) | ||
|
||
func setup(t *testing.T) { | ||
deployLocalStack := !(os.Getenv("DEPLOY_LOCALSTACK") == "false") | ||
|
||
_, b, _, _ := runtime.Caller(0) | ||
rootPath := filepath.Join(filepath.Dir(b), "../../..") | ||
changeDirectory(filepath.Join(rootPath, "inabox")) | ||
|
||
if deployLocalStack { | ||
var err error | ||
dockertestPool, dockertestResource, err = deploy.StartDockertestWithLocalstackContainer(localstackPort) | ||
require.NoError(t, err) | ||
} | ||
} | ||
|
||
func changeDirectory(path string) { | ||
err := os.Chdir(path) | ||
if err != nil { | ||
|
||
currentDirectory, err := os.Getwd() | ||
if err != nil { | ||
log.Printf("Failed to get current directory. Error: %s", err) | ||
} | ||
|
||
log.Panicf("Failed to change directories. CWD: %s, Error: %s", currentDirectory, err) | ||
} | ||
|
||
newDir, err := os.Getwd() | ||
if err != nil { | ||
log.Panicf("Failed to get working directory. Error: %s", err) | ||
} | ||
log.Printf("Current Working Directory: %s\n", newDir) | ||
} | ||
|
||
func teardown() { | ||
deployLocalStack := !(os.Getenv("DEPLOY_LOCALSTACK") == "false") | ||
|
||
if deployLocalStack { | ||
deploy.PurgeDockertestResources(dockertestPool, dockertestResource) | ||
} | ||
} | ||
|
||
func TestRequestSigning(t *testing.T) { | ||
rand := random.NewTestRandom(t) | ||
setup(t) | ||
defer teardown() | ||
|
||
keyManager := kms.New(kms.Options{ | ||
Region: region, | ||
BaseEndpoint: aws.String(localstackHost), | ||
}) | ||
|
||
for i := 0; i < 10; i++ { | ||
createKeyOutput, err := keyManager.CreateKey(context.Background(), &kms.CreateKeyInput{ | ||
KeySpec: types.KeySpecEccSecgP256k1, | ||
KeyUsage: types.KeyUsageTypeSignVerify, | ||
}) | ||
require.NoError(t, err) | ||
|
||
keyID := *createKeyOutput.KeyMetadata.KeyId | ||
|
||
key, err := common.LoadPublicKeyKMS(context.Background(), keyManager, keyID) | ||
require.NoError(t, err) | ||
|
||
publicAddress := crypto.PubkeyToAddress(*key) | ||
|
||
for j := 0; j < 10; j++ { | ||
request := auth.RandomStoreChunksRequest(rand) | ||
request.Signature = nil | ||
|
||
signer, err := NewDispersalRequestSigner(context.Background(), region, localstackHost, keyID) | ||
require.NoError(t, err) | ||
|
||
// Test a valid signature. | ||
signature, err := signer.SignStoreChunksRequest(context.Background(), request) | ||
require.NoError(t, err) | ||
|
||
require.Nil(t, request.Signature) | ||
request.Signature = signature | ||
err = auth.VerifyStoreChunksRequest(publicAddress, request) | ||
require.NoError(t, err) | ||
|
||
// Changing a byte in the middle of the signature should make the verification fail | ||
badSignature := make([]byte, len(signature)) | ||
copy(badSignature, signature) | ||
badSignature[10] = badSignature[10] + 1 | ||
request.Signature = badSignature | ||
err = auth.VerifyStoreChunksRequest(publicAddress, request) | ||
require.Error(t, err) | ||
|
||
// Changing a byte in the middle of the request should make the verification fail | ||
request.DisperserID = request.DisperserID + 1 | ||
request.Signature = signature | ||
err = auth.VerifyStoreChunksRequest(publicAddress, request) | ||
require.Error(t, err) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
package api | ||
|
||
// EigenLabsDisperserID is the ID of the disperser that is managed by Eigen Labs. | ||
const EigenLabsDisperserID = uint32(0) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A slightly different structuring of it: shall we pass in an interface, not a concrete implementation?
Like we have RequestSigners interface (and passed around), but with a KMS based implementation. This leaves space for potential non-KMS (i.e. non AWS specific) options (in a decentralized scenario it may be needed).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a little confused about this comment.
DispersalRequestSigner
is already an interface. Is the interface ok in its current form?