Skip to content

Commit

Permalink
Merge pull request #85 from KirillovDenis/feature/75-using_256r1_inst…
Browse files Browse the repository at this point in the history
…ead_of_ed25519

[#75] Using secp256r1 instead of curve25519
  • Loading branch information
roman-khimov authored Jun 17, 2021
2 parents 43dc730 + 0c03c5f commit c89304d
Show file tree
Hide file tree
Showing 12 changed files with 179 additions and 406 deletions.
21 changes: 6 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,29 +34,22 @@ Minimalistic S3 gateway setup needs:
NeoFS nodes with weighted load balancing).
* a key used to communicate with NeoFS nodes
Passed via `--neofs-key` parameter or `S3_GW_NEOFS-KEY` environment variable.
* a key used for client authentication
Passed via `--auth-key` parameter or `S3_GW_AUTH-KEY` environment variable.
To generate it use `neofs-authmate generate-keys` command.

These two commands are functionally equivalent, they run the gate with one
backend node, some keys and otherwise default settings:
```
$ neofs-s3-gw -p 192.168.130.72:8080 --neofs-key KxDgvEKzgSBPPfuVfw67oPQBSjidEiqTHURKSDL1R7yGaGYAeYnr \
--auth-key a04edd5b3c497eed83be25fb136bafd056928c17986440745775223615f2cbab
$ neofs-s3-gw -p 192.168.130.72:8080 --neofs-key KxDgvEKzgSBPPfuVfw67oPQBSjidEiqTHURKSDL1R7yGaGYAeYnr
$ S3_GW_PEERS_0_ADDRESS=192.168.130.72:8080 \
S3_GW_NEOFS-KEY=KxDgvEKzgSBPPfuVfw67oPQBSjidEiqTHURKSDL1R7yGaGYAeYnr \
S3_GW_AUTH-KEY=a04edd5b3c497eed83be25fb136bafd056928c17986440745775223615f2cbab \
neofs-s3-gw
```
It's also possible to specify uri scheme (grpc or grpcs) when using `-p` or environment variables:
```
$ neofs-s3-gw -p grpc://192.168.130.72:8080 --neofs-key KxDgvEKzgSBPPfuVfw67oPQBSjidEiqTHURKSDL1R7yGaGYAeYnr \
--auth-key a04edd5b3c497eed83be25fb136bafd056928c17986440745775223615f2cbab
$ neofs-s3-gw -p grpc://192.168.130.72:8080 --neofs-key KxDgvEKzgSBPPfuVfw67oPQBSjidEiqTHURKSDL1R7yGaGYAeYnr
$ S3_GW_PEERS_0_ADDRESS=grpcs://192.168.130.72:8080 \
S3_GW_NEOFS-KEY=KxDgvEKzgSBPPfuVfw67oPQBSjidEiqTHURKSDL1R7yGaGYAeYnr \
S3_GW_AUTH-KEY=a04edd5b3c497eed83be25fb136bafd056928c17986440745775223615f2cbab \
neofs-s3-gw
```

Expand Down Expand Up @@ -84,12 +77,10 @@ $ HTTP_GW_PEERS_0_ADDRESS=192.168.130.72:8080 HTTP_GW_PEERS_0_WEIGHT=9 \
This command will make gateway use 192.168.130.72 for 90% of requests and
192.168.130.71 for remaining 10%.

### Keys
### Key

NeoFS (`--neofs-key`) and authentication (`--auth-key`) keys are mandatory
parameters. NeoFS key can be a path to private key file (as raw bytes), a hex
string or (unencrypted) WIF string. Authentication key is either a path to
raw private key file or a hex string.
NeoFS (`--neofs-key`) is mandatory parameter. NeoFS key can be a path to private key file (as raw bytes),
a hex string or (unencrypted) WIF string.

### Binding and TLS

Expand Down Expand Up @@ -208,7 +199,7 @@ potentially).

#### Generation of key pairs

To generate key pairs for gateways, run the following command (`--count` is 1
To generate neofs key pairs for gateways, run the following command (`--count` is 1
by default):

```
Expand Down
9 changes: 4 additions & 5 deletions api/auth/center.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package auth

import (
"context"
"crypto/ecdsa"
"errors"
"fmt"
"io"
Expand All @@ -15,7 +16,6 @@ import (
"github.com/nspcc-dev/neofs-api-go/pkg/object"
"github.com/nspcc-dev/neofs-api-go/pkg/token"
"github.com/nspcc-dev/neofs-s3-gw/authmate"
"github.com/nspcc-dev/neofs-s3-gw/creds/hcs"
"github.com/nspcc-dev/neofs-s3-gw/creds/tokens"
"github.com/nspcc-dev/neofs-sdk-go/pkg/pool"
"go.uber.org/zap"
Expand All @@ -36,9 +36,8 @@ type (

// Params stores node connection parameters.
Params struct {
Pool pool.Pool
Logger *zap.Logger
Credential hcs.Credentials
Pool pool.Pool
Logger *zap.Logger
}

prs int
Expand All @@ -58,7 +57,7 @@ func (p prs) Seek(_ int64, _ int) (int64, error) {
var _ io.ReadSeeker = prs(0)

// New creates an instance of AuthCenter.
func New(conns pool.Pool, key hcs.PrivateKey) Center {
func New(conns pool.Pool, key *ecdsa.PrivateKey) Center {
return &center{
cli: tokens.New(conns, key),
reg: &regexpSubmatcher{re: authorizationFieldRegexp},
Expand Down
79 changes: 47 additions & 32 deletions authmate/authmate.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@ import (
"github.com/nspcc-dev/neofs-api-go/pkg/owner"
"github.com/nspcc-dev/neofs-api-go/pkg/session"
"github.com/nspcc-dev/neofs-api-go/pkg/token"
crypto "github.com/nspcc-dev/neofs-crypto"
"github.com/nspcc-dev/neofs-node/pkg/policy"
"github.com/nspcc-dev/neofs-s3-gw/creds/accessbox"
"github.com/nspcc-dev/neofs-s3-gw/creds/hcs"
"github.com/nspcc-dev/neofs-s3-gw/creds/tokens"
"github.com/nspcc-dev/neofs-sdk-go/pkg/pool"
"go.uber.org/zap"
)

const (
defaultAuthContainerBasicACL uint32 = 0b00111100100011001000110011001100
defaultAuthContainerBasicACL uint32 = 0b00111100100011001000110011001110
containerCreationTimeout = 120 * time.Second
containerPollInterval = 5 * time.Second
)
Expand All @@ -52,8 +52,7 @@ type (
ContainerID *cid.ID
ContainerFriendlyName string
NeoFSKey *ecdsa.PrivateKey
OwnerPrivateKey hcs.PrivateKey
GatesPublicKeys []hcs.PublicKey
GatesPublicKeys []*ecdsa.PublicKey
EACLRules []byte
ContextRules []byte
SessionTkn bool
Expand All @@ -62,7 +61,7 @@ type (
// ObtainSecretOptions contains options for passing to Agent.ObtainSecret method.
ObtainSecretOptions struct {
SecretAddress string
GatePrivateKey hcs.PrivateKey
GatePrivateKey *ecdsa.PrivateKey
}
)

Expand Down Expand Up @@ -134,16 +133,14 @@ func (a *Agent) IssueSecret(ctx context.Context, w io.Writer, options *IssueSecr
var (
err error
cid *cid.ID
box accessbox.AccessBox
box *accessbox.AccessBox
)

a.log.Info("check container", zap.Stringer("cid", options.ContainerID))
if cid, err = a.checkContainer(ctx, options.ContainerID, options.ContainerFriendlyName); err != nil {
return err
}

box.SetOwnerPublicKey(options.OwnerPrivateKey.PublicKey())

oid, err := ownerIDFromNeoFSKey(&options.NeoFSKey.PublicKey)
if err != nil {
return err
Expand All @@ -155,35 +152,24 @@ func (a *Agent) IssueSecret(ctx context.Context, w io.Writer, options *IssueSecr
return fmt.Errorf("failed to build eacl table: %w", err)
}

bearerTkn, err := buildBearerToken(options.NeoFSKey, oid, bearerRules)
bearerTkn, err := buildBearerToken(options.NeoFSKey, bearerRules, options.GatesPublicKeys[0])
if err != nil {
return fmt.Errorf("failed to build bearer token: %w", err)
}

err = box.AddBearerToken(bearerTkn, options.OwnerPrivateKey, options.GatesPublicKeys...)
sessionTkn, err := createSessionToken(options, oid)
if err != nil {
return fmt.Errorf("failed to add bearer token to accessbox: %w", err)
return fmt.Errorf("failed to create session token: %w", err)
}
a.log.Info("store bearer token into NeoFS",
zap.Stringer("owner_tkn", bearerTkn.Issuer()))

if options.SessionTkn {
sessionRules, err := buildContext(options.ContextRules)
if err != nil {
return fmt.Errorf("failed to build context for session token: %w", err)
}

sessionTkn, err := buildSessionToken(options.NeoFSKey, oid, sessionRules)
if err != nil {
return fmt.Errorf("failed to create session token: %w", err)
}

err = box.AddSessionToken(sessionTkn, options.OwnerPrivateKey, options.GatesPublicKeys...)
if err != nil {
return fmt.Errorf("failed to add session token to accessbox: %w", err)
}
box, ownerKey, err := accessbox.PackTokens(bearerTkn, sessionTkn, options.GatesPublicKeys...)
if err != nil {
return err
}

a.log.Info("store bearer token into NeoFS",
zap.Stringer("owner_tkn", bearerTkn.Issuer()))

if !options.SessionTkn && len(options.ContextRules) > 0 {
_, err := w.Write([]byte("Warning: rules for session token were set but --create-session flag wasn't, " +
"so session token was not created\n"))
Expand All @@ -193,8 +179,8 @@ func (a *Agent) IssueSecret(ctx context.Context, w io.Writer, options *IssueSecr
}

address, err := tokens.
New(a.pool, options.OwnerPrivateKey).
Put(ctx, cid, oid, &box, options.GatesPublicKeys...)
New(a.pool, ownerKey).
Put(ctx, cid, oid, box, options.GatesPublicKeys...)
if err != nil {
return fmt.Errorf("failed to put bearer token: %w", err)
}
Expand All @@ -209,7 +195,7 @@ func (a *Agent) IssueSecret(ctx context.Context, w io.Writer, options *IssueSecr
ir := &issuingResult{
AccessKeyID: accessKeyID,
SecretAccessKey: secret,
OwnerPrivateKey: options.OwnerPrivateKey.String(),
OwnerPrivateKey: hex.EncodeToString(crypto.MarshalPrivateKey(ownerKey)),
}

enc := json.NewEncoder(w)
Expand Down Expand Up @@ -316,7 +302,12 @@ func buildContext(rules []byte) (*session.ContainerContext, error) {
return sessionCtx, nil
}

func buildBearerToken(key *ecdsa.PrivateKey, oid *owner.ID, table *eacl.Table) (*token.BearerToken, error) {
func buildBearerToken(key *ecdsa.PrivateKey, table *eacl.Table, ownerKey *ecdsa.PublicKey) (*token.BearerToken, error) {
oid, err := ownerIDFromNeoFSKey(ownerKey)
if err != nil {
return nil, err
}

bearerToken := token.NewBearerToken()
bearerToken.SetEACLTable(table)
bearerToken.SetOwner(oid)
Expand All @@ -338,6 +329,17 @@ func buildSessionToken(key *ecdsa.PrivateKey, oid *owner.ID, ctx *session.Contai
return tok, tok.Sign(key)
}

func createSessionToken(options *IssueSecretOptions, oid *owner.ID) (*session.Token, error) {
if options.SessionTkn {
sessionRules, err := buildContext(options.ContextRules)
if err != nil {
return nil, fmt.Errorf("failed to build context for session token: %w", err)
}
return buildSessionToken(options.NeoFSKey, oid, sessionRules)
}
return nil, nil
}

// BearerToAccessKey returns secret access key generated from given BearerToken.
func BearerToAccessKey(tkn *token.BearerToken) (string, error) {
data, err := tkn.Marshal()
Expand All @@ -356,3 +358,16 @@ func ownerIDFromNeoFSKey(key *ecdsa.PublicKey) (*owner.ID, error) {
}
return owner.NewIDFromNeo3Wallet(wallet), nil
}

// LoadPublicKey returns ecdsa.PublicKey from hex string.
func LoadPublicKey(val string) (*ecdsa.PublicKey, error) {
data, err := hex.DecodeString(val)
if err != nil {
return nil, fmt.Errorf("unknown key format (%q), expect: hex-string", val)
}

if key := crypto.UnmarshalPublicKey(data); key != nil {
return key, nil
}
return nil, fmt.Errorf("couldn't unmarshal public key (%q)", val)
}
Loading

0 comments on commit c89304d

Please sign in to comment.