Skip to content

Commit

Permalink
authentication tests with in-memory signer
Browse files Browse the repository at this point in the history
  • Loading branch information
e-asphyx committed Jul 27, 2021
1 parent 355f8fa commit 44e4692
Show file tree
Hide file tree
Showing 11 changed files with 327 additions and 121 deletions.
1 change: 0 additions & 1 deletion cmd/genkey/.gitignore

This file was deleted.

91 changes: 0 additions & 91 deletions cmd/genkey/genkey.go

This file was deleted.

1 change: 1 addition & 0 deletions cmd/signatory-tools/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
signatory-tools
56 changes: 56 additions & 0 deletions cmd/signatory-tools/authenticate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package main

import (
"encoding/hex"
"fmt"

"github.com/ecadlabs/signatory/pkg/cryptoutils"
"github.com/ecadlabs/signatory/pkg/signatory"
"github.com/ecadlabs/signatory/pkg/tezos"
"github.com/spf13/cobra"
)

func NewAuthRequestCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "authenticate <secret key> <request pkh> <request body>",
Short: "Authenticate (sign) a sign request",
Args: cobra.ExactArgs(3),
RunE: func(cmd *cobra.Command, args []string) error {
priv, err := tezos.ParsePrivateKey(args[0], nil)
if err != nil {
return err
}

msg, err := hex.DecodeString(args[2])
if err != nil {
return err
}

req := signatory.SignRequest{
Message: msg,
PublicKeyHash: args[1],
}

data, err := signatory.SignRequestAuthenticatedBytes(&req)
if err != nil {
return err
}

digest := tezos.DigestFunc(data)
sig, err := cryptoutils.Sign(priv, digest[:])
if err != nil {
return err
}

res, err := tezos.EncodeSignature(sig)
if err != nil {
return err
}

fmt.Println(res)
return nil
},
}

return cmd
}
92 changes: 92 additions & 0 deletions cmd/signatory-tools/genkey.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package main

import (
"crypto/ecdsa"
"crypto/ed25519"
"crypto/elliptic"
"crypto/rand"
"fmt"
"os"
"text/template"

"github.com/ecadlabs/signatory/pkg/cryptoutils"
"github.com/ecadlabs/signatory/pkg/tezos"
"github.com/spf13/cobra"
)

const genkeyTemplateSrc = `{{range . -}}
Private Key: {{.PrivateKey}}
Public Key: {{.PublicKey}}
Public Key Hash: {{.PublicKeyHash}}
{{end}}
`

var (
genkeyTpl = template.Must(template.New("list").Parse(genkeyTemplateSrc))
)

type tplData struct {
PrivateKey string
PublicKey string
PublicKeyHash string
}

func NewGenKeyCommand() *cobra.Command {
var (
keyType string
num int
)

cmd := &cobra.Command{
Use: "gen-key",
Short: "Generate a key pair",
RunE: func(cmd *cobra.Command, args []string) error {
var data []*tplData
for i := 0; i < num; i++ {
var (
pk cryptoutils.PrivateKey
err error
)

switch keyType {
case "edsk":
_, pk, err = ed25519.GenerateKey(rand.Reader)
case "spsk":
pk, err = ecdsa.GenerateKey(cryptoutils.S256(), rand.Reader)
case "p2sk":
pk, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
default:
err = fmt.Errorf("unknown key type: %s", keyType)
}

if err != nil {
return err
}

var d tplData
if d.PrivateKey, err = tezos.EncodePrivateKey(pk); err != nil {
return err
}
if d.PublicKey, err = tezos.EncodePublicKey(pk.Public()); err != nil {
return err
}
if d.PublicKeyHash, err = tezos.EncodePublicKeyHash(pk.Public()); err != nil {
return err
}
data = append(data, &d)
}

if err := genkeyTpl.Execute(os.Stdout, data); err != nil {
return err
}

return nil
},
}

cmd.Flags().IntVar(&num, "n", 1, "Number of key pairs to generate")
cmd.Flags().StringVar(&keyType, "t", "edsk", "Key type [edsk, spsk, p2sk]")

return cmd
}
21 changes: 21 additions & 0 deletions cmd/signatory-tools/tools.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package main

import (
"os"

"github.com/spf13/cobra"
)

func main() {
rootCmd := &cobra.Command{
Use: "signatory-tools",
Short: "Various Signatory tools",
}

rootCmd.AddCommand(NewGenKeyCommand())
rootCmd.AddCommand(NewAuthRequestCommand())

if err := rootCmd.Execute(); err != nil {
os.Exit(1)
}
}
125 changes: 125 additions & 0 deletions integration_test/auth_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package integrationtest_test

import (
"context"
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"

"github.com/ecadlabs/signatory/pkg/config"
"github.com/ecadlabs/signatory/pkg/server"
"github.com/ecadlabs/signatory/pkg/server/auth"
"github.com/ecadlabs/signatory/pkg/signatory"
"github.com/ecadlabs/signatory/pkg/tezos"
"github.com/ecadlabs/signatory/pkg/vault"
"github.com/ecadlabs/signatory/pkg/vault/memory"
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v3"
)

/*
Auth:
Private Key: edsk3xMUYWwM2Gstbeeyd1pvsoYoGGdhjej1jGZk2EdMpYsgZcj5Pm
Public Key: edpkvN5hM4s88nzgxZGkNrVqtQfaiVpix356TFrAwQoVGrKseahWG6
Public Key Hash: tz1KpduK2jQizMyLSfycjDmbBijWK1kpemJ3
Private Key: edsk32vZZSKSLWDCUFKSbLYvv9GNAS3ErBftYfFgG1RiDbve5MoN5P
Public Key: edpkuv8KcJf1aG6vsJa1XuXsqto39tHNd8YB6qfZQ6FUX6ikQoh5Dq
Public Key Hash: tz1LaPcNukJrEEJoNp2UqnhGfcqQtDPtSQ5o
Sign:
Private Key: edsk3K3EwiTVXtEnfuERrjzjp3pa6pRrvQE3VA97cModhXVhXpnsAQ
Public Key: edpkvVV6zH5xxewkxPN98SUTspBjYmDYZPX6PGSSDjCK5iDoT8vDQV
Public Key Hash: tz1cJaw1s1o6o2hMv9r9Q8HWwJLAnD9wqg26
*/

func TestAuthenticatedRequestInMemoryVault(t *testing.T) {
type testCase struct {
name string
signature string
statusCode int
}

cases := []testCase{
{
name: "Ok",
signature: "edsigtkjMUUeReAm22MSYW5eR5gby4RQZfjakeKV2zwDwXmF4Gxe68zMuMK8scrbESDHWbPRkebQPVrdnsUsJ46pfP4hXT8oXZZ",
statusCode: http.StatusOK,
},
{
name: "No signature",
statusCode: http.StatusUnauthorized,
},
{
name: "Disabled in policy",
signature: "edsigtbakQb6EmsjHpXvjqDTre3EmauHei6LCqhBhRp6neyBNL2F3FX3jQsM9n8KYefWnjUABBWeATEAimaLZGSoGVqHjLc6NLM",
statusCode: http.StatusForbidden,
},
{
name: "Invalid signature",
signature: "spsig1SbAZ2AWQP6fXYusCW8XowTxieZw874YcuBtKYkGEEDrvyTgReLY3jKAuoBamBALRtrEsEMG5N7zxmuxfE9MDLgsMP1YJh",
statusCode: http.StatusForbidden,
},
}

pk := "edsk3K3EwiTVXtEnfuERrjzjp3pa6pRrvQE3VA97cModhXVhXpnsAQ"
message := "\"03a11f5f176e553a11cf184bb2b15f09f55dfc5dcb2d26d79bf5dd099d074d5f5d6c0079cae4c9a1885f17d3995619bf28636c4394458b820af19172c35000904e0000712c4c4270d9e7f512115310d8ec6acfcd878bef00\""

priv, err := tezos.ParsePrivateKey(pk, nil)
require.NoError(t, err)

pub, err := tezos.EncodePublicKeyHash(priv.Public())
require.NoError(t, err)

conf := signatory.Config{
Vaults: map[string]*config.VaultConfig{"mock": {Driver: "mock"}},
Watermark: signatory.IgnoreWatermark{},
VaultFactory: vault.FactoryFunc(func(ctx context.Context, name string, conf *yaml.Node) (vault.Vault, error) {
return memory.NewUnparsed([]*memory.UnparsedKey{{Data: pk}}, "Mock"), nil
}),
Policy: map[string]*signatory.Policy{
pub: {
AllowedOperations: []string{"generic", "block", "endorsement"},
AllowedKinds: []string{"endorsement", "seed_nonce_revelation", "activate_account", "ballot", "reveal", "transaction", "origination", "delegation"},
AuthorizedKeyHashes: []string{"tz1KpduK2jQizMyLSfycjDmbBijWK1kpemJ3"},
},
},
}

signer, err := signatory.New(context.Background(), &conf)
require.NoError(t, err)
require.NoError(t, signer.Unlock(context.Background()))

srv := server.Server{
Signer: signer,
Auth: auth.Must(auth.StaticAuthorizedKeysFromString("edpkvN5hM4s88nzgxZGkNrVqtQfaiVpix356TFrAwQoVGrKseahWG6", "edpkuv8KcJf1aG6vsJa1XuXsqto39tHNd8YB6qfZQ6FUX6ikQoh5Dq")),
}

handler, err := srv.Handler()
require.NoError(t, err)

s := httptest.NewServer(handler)
defer s.Close()

for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
body := strings.NewReader(message)
u, _ := url.Parse(s.URL + "/keys/" + pub)
if c.signature != "" {
u.RawQuery = url.Values{
"authentication": []string{c.signature},
}.Encode()
}

req, err := http.NewRequest("POST", u.String(), body)
require.NoError(t, err)

resp, err := s.Client().Do(req)
require.NoError(t, err)

require.Equal(t, c.statusCode, resp.StatusCode)
})
}
}
Loading

0 comments on commit 44e4692

Please sign in to comment.