dbe65ae602
Mostly taken from old SDK (abe47687cd11266f946cad57f07572cc10c67226), but error handling adapted to eliminate pkg/errors and internal packages. Signed-off-by: Roman Khimov <roman@nspcc.ru>
161 lines
4 KiB
Go
161 lines
4 KiB
Go
package accessbox
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/ecdsa"
|
|
"crypto/elliptic"
|
|
"crypto/rand"
|
|
"encoding/binary"
|
|
"strconv"
|
|
"testing"
|
|
|
|
"github.com/nspcc-dev/neofs-s3-gw/creds/hcs"
|
|
"github.com/nspcc-dev/neofs-api-go/pkg/acl/eacl"
|
|
"github.com/nspcc-dev/neofs-api-go/pkg/token"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func Test_encrypt_decrypt(t *testing.T) {
|
|
tkn := token.NewBearerToken()
|
|
box := NewBearerBox(tkn)
|
|
|
|
sec, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
require.NoError(t, err)
|
|
|
|
cred, err := hcs.Generate(rand.Reader)
|
|
require.NoError(t, err)
|
|
|
|
tkn.SetEACLTable(eacl.NewTable())
|
|
require.NoError(t, tkn.SignToken(sec))
|
|
|
|
data, err := box.Marshal()
|
|
require.NoError(t, err)
|
|
|
|
encrypted, err := encrypt(cred.PrivateKey(), cred.PublicKey(), data)
|
|
require.NoError(t, err)
|
|
|
|
decrypted, err := decrypt(cred.PrivateKey(), cred.PublicKey(), encrypted)
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, data, decrypted)
|
|
}
|
|
|
|
func Test_encrypt_decrypt_step_by_step(t *testing.T) {
|
|
tkn := token.NewBearerToken()
|
|
box := NewBearerBox(tkn)
|
|
|
|
sec, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
require.NoError(t, err)
|
|
|
|
cred, err := hcs.Generate(rand.Reader)
|
|
require.NoError(t, err)
|
|
|
|
tkn.SetEACLTable(eacl.NewTable())
|
|
require.NoError(t, tkn.SignToken(sec))
|
|
|
|
data, err := box.Marshal()
|
|
require.NoError(t, err)
|
|
|
|
buf := new(bytes.Buffer)
|
|
_, err = cred.PublicKey().WriteTo(buf)
|
|
require.NoError(t, err)
|
|
|
|
encrypted, err := encrypt(cred.PrivateKey(), cred.PublicKey(), data)
|
|
require.NoError(t, err)
|
|
|
|
length := len(encrypted)
|
|
temp := make([]byte, length+binary.MaxVarintLen64)
|
|
size := binary.PutVarint(temp, int64(length))
|
|
copy(temp[size:], encrypted)
|
|
buf.Write(temp[:length+size])
|
|
|
|
sender, err := hcs.NewPublicKeyFromReader(buf)
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, cred.PublicKey(), sender)
|
|
|
|
ln, err := binary.ReadVarint(buf)
|
|
require.NoError(t, err)
|
|
require.Equal(t, int64(length), ln)
|
|
|
|
enc := make([]byte, ln)
|
|
n, err := buf.Read(enc)
|
|
require.NoError(t, err)
|
|
require.Equal(t, length, n)
|
|
require.Equal(t, encrypted, enc)
|
|
|
|
decrypted, err := decrypt(cred.PrivateKey(), sender, enc)
|
|
require.NoError(t, err)
|
|
require.Equal(t, data, decrypted)
|
|
}
|
|
|
|
func TestSingleKey_AccessBox(t *testing.T) {
|
|
tkn := token.NewBearerToken()
|
|
expect := NewBearerBox(tkn)
|
|
actual := NewBearerBox(nil)
|
|
|
|
sec, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
require.NoError(t, err)
|
|
|
|
cred, err := hcs.Generate(rand.Reader)
|
|
require.NoError(t, err)
|
|
|
|
tkn.SetEACLTable(eacl.NewTable())
|
|
require.NoError(t, tkn.SignToken(sec))
|
|
|
|
data, err := Encode(expect, cred.PrivateKey(), cred.PublicKey())
|
|
require.NoError(t, err)
|
|
|
|
require.NoError(t, Decode(data, actual, cred.PrivateKey()))
|
|
require.Equal(t, expect, actual)
|
|
}
|
|
|
|
func TestBearerToken_AccessBox(t *testing.T) {
|
|
tkn := token.NewBearerToken()
|
|
box := NewBearerBox(tkn)
|
|
sec, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
require.NoError(t, err)
|
|
|
|
cred, err := hcs.Generate(rand.Reader)
|
|
require.NoError(t, err)
|
|
|
|
tkn.SetEACLTable(eacl.NewTable())
|
|
require.NoError(t, tkn.SignToken(sec))
|
|
|
|
count := 10
|
|
pubs := make([]hcs.PublicKey, 0, count)
|
|
keys := make([]hcs.PrivateKey, 0, count)
|
|
{ // generate keys
|
|
for i := 0; i < count; i++ {
|
|
cred, err := hcs.Generate(rand.Reader)
|
|
require.NoError(t, err)
|
|
|
|
pubs = append(pubs, cred.PublicKey())
|
|
keys = append(keys, cred.PrivateKey())
|
|
}
|
|
}
|
|
|
|
buf := new(bytes.Buffer)
|
|
require.NoError(t, NewEncoder(buf, cred.PrivateKey(), pubs...).Encode(box))
|
|
|
|
data := buf.Bytes()
|
|
|
|
for i := range keys {
|
|
key := keys[i]
|
|
t.Run("try with key "+strconv.Itoa(i), func(t *testing.T) {
|
|
r := bytes.NewReader(data)
|
|
nbx := NewBearerBox(nil)
|
|
require.NoError(t, NewDecoder(r, key).Decode(nbx))
|
|
require.Equal(t, tkn, nbx.Token())
|
|
})
|
|
}
|
|
|
|
t.Run("should fail for unknown key", func(t *testing.T) {
|
|
cred, err = hcs.Generate(rand.Reader)
|
|
require.NoError(t, err)
|
|
|
|
r := bytes.NewReader(data)
|
|
nbx := NewBearerBox(nil)
|
|
require.EqualError(t, NewDecoder(r, cred.PrivateKey()).Decode(nbx), "chacha20poly1305: message authentication failed")
|
|
})
|
|
}
|