代码拉取完成,页面将自动刷新
// Copyright 2018-2024 The NATS Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package nkeys
import (
"bytes"
"crypto/ed25519"
"crypto/rand"
"encoding/base64"
"io"
"os"
"regexp"
"testing"
)
func TestVersion(t *testing.T) {
// Semantic versioning
verRe := regexp.MustCompile(`\d+.\d+.\d+(-\S+)?`)
if !verRe.MatchString(Version) {
t.Fatalf("Version not compatible with semantic versioning: %q", Version)
}
}
func TestVersionMatchesTag(t *testing.T) {
tag := os.Getenv("TRAVIS_TAG")
if tag == "" {
t.SkipNow()
}
// We expect a tag of the form vX.Y.Z. If that's not the case,
// we need someone to have a look. So fail if first letter is not
// a `v`
if tag[0] != 'v' {
t.Fatalf("Expect tag to start with `v`, tag is: %s", tag)
}
// Strip the `v` from the tag for the version comparison.
if Version != tag[1:] {
t.Fatalf("Version (%s) does not match tag (%s)", Version, tag[1:])
}
}
func TestEncode(t *testing.T) {
var rawKey [32]byte
_, err := io.ReadFull(rand.Reader, rawKey[:])
if err != nil {
t.Fatalf("Unexpected error reading from crypto/rand: %v", err)
}
_, err = Encode(PrefixByteUser, rawKey[:])
if err != nil {
t.Fatalf("Unexpected error from Encode: %v", err)
}
str, err := Encode(22<<3, rawKey[:])
if err == nil {
t.Fatal("Expected an error from Encode but received nil")
}
if str != nil {
t.Fatalf("Expected empty string from Encode: got %s", str)
}
}
func TestDecode(t *testing.T) {
var rawKey [32]byte
_, err := io.ReadFull(rand.Reader, rawKey[:])
if err != nil {
t.Fatalf("Unexpected error reading from crypto/rand: %v", err)
}
str, err := Encode(PrefixByteUser, rawKey[:])
if err != nil {
t.Fatalf("Unexpected error from Encode: %v", err)
}
decoded, err := Decode(PrefixByteUser, str)
if err != nil {
t.Fatalf("Unexpected error from Decode: %v", err)
}
if !bytes.Equal(decoded, rawKey[:]) {
t.Fatalf("Decoded does not match the original")
}
}
func TestSeed(t *testing.T) {
var rawKeyShort [16]byte
_, err := io.ReadFull(rand.Reader, rawKeyShort[:])
if err != nil {
t.Fatalf("Unexpected error reading from crypto/rand: %v", err)
}
// Seeds need to be 64 bytes
if _, err := EncodeSeed(PrefixByteUser, rawKeyShort[:]); err != ErrInvalidSeedLen {
t.Fatalf("Did not receive ErrInvalidSeed error, received %v", err)
}
// Seeds need to be typed with only public types.
if _, err := EncodeSeed(PrefixByteSeed, rawKeyShort[:]); err != ErrInvalidPrefixByte {
t.Fatalf("Did not receive ErrInvalidPrefixByte error, received %v", err)
}
var rawSeed [ed25519.SeedSize]byte
_, err = io.ReadFull(rand.Reader, rawSeed[:])
if err != nil {
t.Fatalf("Unexpected error reading from crypto/rand: %v", err)
}
seed, err := EncodeSeed(PrefixByteUser, rawSeed[:])
if err != nil {
t.Fatalf("EncodeSeed received an error: %v", err)
}
pre, decoded, err := DecodeSeed(seed)
if err != nil {
t.Fatalf("Got an unexpected error from DecodeSeed: %v", err)
}
if pre != PrefixByteUser {
t.Fatalf("Expected the prefix to be PrefixByteUser(%v), got %v",
PrefixByteUser, pre)
}
if !bytes.Equal(decoded, rawSeed[:]) {
t.Fatalf("Decoded seed does not match the original")
}
}
func TestAccount(t *testing.T) {
account, err := CreateAccount()
if err != nil {
t.Fatalf("Expected non-nil error on CreateAccount, received %v", err)
}
if account == nil {
t.Fatal("Expect a non-nil account")
}
seed, err := account.Seed()
if err != nil {
t.Fatalf("Unexpected error retrieving seed: %v", err)
}
_, err = Decode(PrefixByteSeed, seed)
if err != nil {
t.Fatalf("Expected a proper seed string, got %s", seed)
}
// Check Public
public, err := account.PublicKey()
if err != nil {
t.Fatalf("Received an error retrieving public key: %v", err)
}
if public[0] != 'A' {
t.Fatalf("Expected a prefix of 'A' but got %c", public[0])
}
if !IsValidPublicAccountKey(public) {
t.Fatalf("Not a valid public account key")
}
// Check Private
private, err := account.PrivateKey()
if err != nil {
t.Fatalf("Received an error retrieving private key: %v", err)
}
if private[0] != 'P' {
t.Fatalf("Expected a prefix of 'P' but got %v", private[0])
}
// Check Sign and Verify
data := []byte("Hello World")
sig, err := account.Sign(data)
if err != nil {
t.Fatalf("Unexpected error signing from account: %v", err)
}
if len(sig) != ed25519.SignatureSize {
t.Fatalf("Expected signature size of %d but got %d",
ed25519.SignatureSize, len(sig))
}
err = account.Verify(data, sig)
if err != nil {
t.Fatalf("Unexpected error verifying signature: %v", err)
}
}
func TestUser(t *testing.T) {
user, err := CreateUser()
if err != nil {
t.Fatalf("Expected non-nil error on CreateUser, received %v", err)
}
if user == nil {
t.Fatal("Expect a non-nil user")
}
// Check Public
public, err := user.PublicKey()
if err != nil {
t.Fatalf("Received an error retrieving public key: %v", err)
}
if public[0] != 'U' {
t.Fatalf("Expected a prefix of 'U' but got %c", public[0])
}
if !IsValidPublicUserKey(public) {
t.Fatalf("Not a valid public user key")
}
}
func TestOperator(t *testing.T) {
operator, err := CreateOperator()
if err != nil {
t.Fatalf("Expected non-nil error on CreateOperator, received %v", err)
}
if operator == nil {
t.Fatal("Expect a non-nil operator")
}
// Check Public
public, err := operator.PublicKey()
if err != nil {
t.Fatalf("Received an error retrieving public key: %v", err)
}
if public[0] != 'O' {
t.Fatalf("Expected a prefix of 'O' but got %c", public[0])
}
if !IsValidPublicOperatorKey(public) {
t.Fatalf("Not a valid public cluster key")
}
}
func TestCluster(t *testing.T) {
cluster, err := CreateCluster()
if err != nil {
t.Fatalf("Expected non-nil error on CreateCluster, received %v", err)
}
if cluster == nil {
t.Fatal("Expect a non-nil cluster")
}
// Check Public
public, err := cluster.PublicKey()
if err != nil {
t.Fatalf("Received an error retrieving public key: %v", err)
}
if public[0] != 'C' {
t.Fatalf("Expected a prefix of 'C' but got %c", public[0])
}
if !IsValidPublicClusterKey(public) {
t.Fatalf("Not a valid public cluster key")
}
}
func TestServer(t *testing.T) {
server, err := CreateServer()
if err != nil {
t.Fatalf("Expected non-nil error on CreateServer, received %v", err)
}
if server == nil {
t.Fatal("Expect a non-nil server")
}
// Check Public
public, err := server.PublicKey()
if err != nil {
t.Fatalf("Received an error retrieving public key: %v", err)
}
if public[0] != 'N' {
t.Fatalf("Expected a prefix of 'N' but got %c", public[0])
}
if !IsValidPublicServerKey(public) {
t.Fatalf("Not a valid public server key")
}
}
func TestPrefixByte(t *testing.T) {
user, _ := CreateUser()
pub, _ := user.PublicKey()
if pre := Prefix(pub); pre != PrefixByteUser {
t.Fatalf("Expected %s, got %s\n", PrefixByteUser, pre)
}
seed, _ := user.Seed()
if pre := Prefix(string(seed)); pre != PrefixByteSeed {
t.Fatalf("Expected %s, got %s\n", PrefixByteSeed, pre)
}
if pre := Prefix("SEED"); pre != PrefixByteUnknown {
t.Fatalf("Expected %s, got %s\n", PrefixByteUnknown, pre)
}
account, _ := CreateAccount()
pub, _ = account.PublicKey()
if pre := Prefix(pub); pre != PrefixByteAccount {
t.Fatalf("Expected %s, got %s\n", PrefixByteAccount, pre)
}
}
func TestIsValidPublic(t *testing.T) {
user, _ := CreateUser()
pub, _ := user.PublicKey()
if !IsValidPublicKey(pub) {
t.Fatalf("Expected pub to be a valid public key")
}
seed, _ := user.Seed()
if IsValidPublicKey(string(seed)) {
t.Fatalf("Expected seed to not be a valid public key")
}
if IsValidPublicKey("BAD") {
t.Fatalf("Expected BAD to not be a valid public key")
}
account, _ := CreateAccount()
pub, _ = account.PublicKey()
if !IsValidPublicKey(pub) {
t.Fatalf("Expected pub to be a valid public key")
}
}
func TestFromPublic(t *testing.T) {
// Create a User
user, err := CreateUser()
if err != nil {
t.Fatalf("Expected non-nil error on CreateUser, received %v", err)
}
if user == nil {
t.Fatal("Expect a non-nil user")
}
// Now create a publickey only KeyPair
publicKey, err := user.PublicKey()
if err != nil {
t.Fatalf("Error retrieving public key from user: %v", err)
}
publicKeyClone, _ := user.PublicKey()
if publicKeyClone != publicKey {
t.Fatalf("Expected the public keys to match: %q vs %q", publicKeyClone, publicKey)
}
pubUser, err := FromPublicKey(publicKey)
if err != nil {
t.Fatalf("Error creating public key only user: %v", err)
}
publicKey2, err := pubUser.PublicKey()
if err != nil {
t.Fatalf("Error retrieving public key from public user: %v", err)
}
// Make sure they match
if publicKey2 != publicKey {
t.Fatalf("Expected the public keys to match: %q vs %q", publicKey2, publicKey)
}
if _, err = pubUser.PrivateKey(); err == nil {
t.Fatalf("Expected and error trying to get private key")
}
if _, err := pubUser.Seed(); err == nil {
t.Fatalf("Expected and error trying to get seed")
}
data := []byte("Hello World")
// Can't sign..
if _, err = pubUser.Sign(data); err != ErrCannotSign {
t.Fatalf("Expected %v, but got %v", ErrCannotSign, err)
}
// Should be able to verify with pubUser.
sig, err := user.Sign(data)
if err != nil {
t.Fatalf("Unexpected error signing from user: %v", err)
}
err = pubUser.Verify(data, sig)
if err != nil {
t.Fatalf("Unexpected error verifying signature: %v", err)
}
// Create another user to sign and make sure verify fails.
user2, _ := CreateUser()
sig, _ = user2.Sign(data)
err = pubUser.Verify(data, sig)
if err == nil {
t.Fatalf("Expected verification to fail.")
}
}
func TestFromSeed(t *testing.T) {
account, err := CreateAccount()
if err != nil {
t.Fatalf("Expected non-nil error on CreateAccount, received %v", err)
}
if account == nil {
t.Fatal("Expect a non-nil account")
}
data := []byte("Hello World")
sig, err := account.Sign(data)
if err != nil {
t.Fatalf("Unexpected error signing from account: %v", err)
}
seed, err := account.Seed()
if err != nil {
t.Fatalf("Unexpected error retrieving seed: %v", err)
}
// Make sure the seed starts with SA
if !bytes.HasPrefix(seed, []byte("SA")) {
t.Fatalf("Expected seed to start with 'SA', go '%s'", seed[:2])
}
account2, err := FromSeed(seed)
if err != nil {
t.Fatalf("Error recreating account from seed: %v", err)
}
if account2 == nil {
t.Fatal("Expect a non-nil account")
}
err = account2.Verify(data, sig)
if err != nil {
t.Fatalf("Unexpected error verifying signature: %v", err)
}
}
func TestKeyPairFailures(t *testing.T) {
var tooshort [8]byte
if _, err := EncodeSeed(PrefixByteUser, tooshort[:]); err == nil {
t.Fatal("Expected an error with insufficient rand")
}
if _, err := CreatePair(PrefixBytePrivate); err == nil {
t.Fatal("Expected an error with non-public prefix")
}
kpbad := &kp{[]byte("SEEDBAD")}
if _, _, err := kpbad.keys(); err == nil {
t.Fatal("Expected an error decoding keys with a bad seed")
}
if _, err := kpbad.PublicKey(); err == nil {
t.Fatal("Expected an error getting PublicKey from KP with a bad seed")
}
if _, err := kpbad.PrivateKey(); err == nil {
t.Fatal("Expected an error getting PrivateKey from KP with a bad seed")
}
if _, err := kpbad.Sign([]byte("ok")); err == nil {
t.Fatal("Expected an error from Signing from KP with a bad seed")
}
}
func TestBadDecode(t *testing.T) {
if _, err := decode([]byte("foo!")); err == nil {
t.Fatal("Expected an error decoding non-base32")
}
if _, err := decode([]byte("OK")); err == nil {
t.Fatal("Expected an error decoding a too short string")
}
// Create invalid checksum
account, _ := CreateAccount()
pkey, _ := account.PublicKey()
bpkey := []byte(pkey)
bpkey[len(pkey)-1] = '0'
bpkey[len(pkey)-2] = '0'
if _, err := decode(bpkey); err == nil {
t.Fatal("Expected error on decode with bad checksum")
}
if _, err := Decode(PrefixByteUser, []byte(pkey)); err == nil {
t.Fatal("Expected error on Decode with mismatched prefix")
}
if _, err := Decode(PrefixByte(3<<3), []byte(pkey)); err == nil {
t.Fatal("Expected error on Decode with invalid prefix")
}
if _, err := Decode(PrefixByteAccount, bpkey); err == nil {
t.Fatal("Expected error on Decode with bad checksum")
}
// Seed version
if _, _, err := DecodeSeed(bpkey); err == nil {
t.Fatal("Expected error on DecodeSeed with bad checksum")
}
if _, _, err := DecodeSeed([]byte(pkey)); err == nil {
t.Fatal("Expected error on DecodeSeed with bad seed type")
}
seed, _ := account.Seed()
bseed := []byte(seed)
bseed[1] = 'S'
if _, _, err := DecodeSeed(bseed); err == nil {
t.Fatal("Expected error on DecodeSeed with bad prefix type")
}
if _, err := FromSeed(bseed); err == nil {
t.Fatal("Expected error on FromSeed with bad prefix type")
}
if _, err := FromPublicKey(string(bpkey)); err == nil {
t.Fatal("Expected error on FromPublicKey with bad checksum")
}
if _, err := FromPublicKey(string(seed)); err == nil {
t.Fatal("Expected error on FromPublicKey with bad checksum")
}
}
func TestFromRawSeed(t *testing.T) {
user, err := CreateUser()
if err != nil {
t.Fatalf("Expected non-nil error on CreateUser, received %v", err)
}
se, _ := user.Seed()
_, raw, _ := DecodeSeed(se)
user2, err := FromRawSeed(PrefixByteUser, raw)
if err != nil {
t.Fatalf("Expected non-nil error on FromRawSeed, received %v", err)
}
s2e, _ := user2.Seed()
if !bytes.Equal(se, s2e) {
t.Fatalf("Expected the seeds to be the same, got %v vs %v\n", se, s2e)
}
}
func TestWipe(t *testing.T) {
user, err := CreateUser()
if err != nil {
t.Fatalf("Expected non-nil error on CreateUser, received %v", err)
}
pubKey, err := user.PublicKey()
if err != nil {
t.Fatalf("Received an error retrieving public key: %v", err)
}
seed := user.(*kp).seed
// Copy so we know the original
copy := append([]byte{}, seed...)
user.Wipe()
// Make sure new seed is nil
if wiped := user.(*kp).seed; wiped != nil {
t.Fatalf("Expected the seed to be nil, got %q", wiped)
}
// Make sure the original seed is not equal to the seed in memory.
if bytes.Equal(seed, copy) {
t.Fatalf("Expected the memory for the seed to be randomized")
}
// Now test public
user, err = FromPublicKey(pubKey)
if err != nil {
t.Fatalf("Received an error create KeyPair from PublicKey: %v", err)
}
edPub := user.(*pub).pub
// Copy so we know the original
copy = append([]byte{}, edPub...)
user.Wipe()
// First check pre was changed
if user.(*pub).pre != '0' {
t.Fatalf("Expected prefix to be changed")
}
// Make sure the original key is not equal to the one in memory.
if bytes.Equal(edPub, copy) {
t.Fatalf("Expected the memory for the pubKey to be randomized")
}
}
const (
nonceRawLen = 16
nonceLen = 22 // base64.RawURLEncoding.EncodedLen(nonceRawLen)
)
func BenchmarkSign(b *testing.B) {
data := make([]byte, nonceRawLen)
nonce := make([]byte, nonceLen)
rand.Read(data)
base64.RawURLEncoding.Encode(nonce, data)
user, err := CreateUser()
if err != nil {
b.Fatalf("Error creating User Nkey: %v", err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
if _, err := user.Sign(nonce); err != nil {
b.Fatalf("Error signing nonce: %v", err)
}
}
}
func BenchmarkVerify(b *testing.B) {
data := make([]byte, nonceRawLen)
nonce := make([]byte, nonceLen)
rand.Read(data)
base64.RawURLEncoding.Encode(nonce, data)
user, err := CreateUser()
if err != nil {
b.Fatalf("Error creating User Nkey: %v", err)
}
sig, err := user.Sign(nonce)
if err != nil {
b.Fatalf("Error sigining nonce: %v", err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
if err := user.Verify(nonce, sig); err != nil {
b.Fatalf("Error verifying nonce: %v", err)
}
}
}
func BenchmarkPublicVerify(b *testing.B) {
data := make([]byte, nonceRawLen)
nonce := make([]byte, nonceLen)
rand.Read(data)
base64.RawURLEncoding.Encode(nonce, data)
user, err := CreateUser()
if err != nil {
b.Fatalf("Error creating User Nkey: %v", err)
}
sig, err := user.Sign(nonce)
if err != nil {
b.Fatalf("Error sigining nonce: %v", err)
}
pk, err := user.PublicKey()
if err != nil {
b.Fatalf("Could not extract public key from user: %v", err)
}
pub, err := FromPublicKey(pk)
if err != nil {
b.Fatalf("Could not create public key pair from public key string: %v", err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
if err := pub.Verify(nonce, sig); err != nil {
b.Fatalf("Error verifying nonce: %v", err)
}
}
}
func TestValidateKeyPairRole(t *testing.T) {
okp, err := CreateOperator()
if err != nil {
t.Fatal(err)
}
akp, err := CreateAccount()
if err != nil {
t.Fatal(err)
}
ukp, err := CreateUser()
if err != nil {
t.Fatal(err)
}
ckp, err := CreateCluster()
if err != nil {
t.Fatal(err)
}
skp, err := CreateServer()
if err != nil {
t.Fatal(err)
}
var keyroles = []struct {
kp KeyPair
roles []PrefixByte
ok bool
name string
}{
{kp: okp, name: "want operator", roles: []PrefixByte{PrefixByteOperator}, ok: true},
{kp: akp, name: "want account", roles: []PrefixByte{PrefixByteAccount}, ok: true},
{kp: ukp, name: "want user", roles: []PrefixByte{PrefixByteUser}, ok: true},
{kp: ckp, name: "want cluster", roles: []PrefixByte{PrefixByteCluster}, ok: true},
{kp: skp, name: "want server", roles: []PrefixByte{PrefixByteServer}, ok: true},
{kp: okp, name: "want account or operator", roles: []PrefixByte{PrefixByteOperator, PrefixByteAccount}, ok: true},
{kp: akp, name: "want account or operator", roles: []PrefixByte{PrefixByteOperator, PrefixByteAccount}, ok: true},
{kp: akp, name: "want operator got account", roles: []PrefixByte{PrefixByteOperator}, ok: false},
{kp: ukp, name: "want account or operator got user", roles: []PrefixByte{PrefixByteOperator, PrefixByteAccount}, ok: false},
}
for _, e := range keyroles {
err := CompatibleKeyPair(e.kp, e.roles...)
if err == nil && !e.ok {
t.Fatalf("test %q should have failed but didn't", e.name)
}
if err != nil && e.ok {
t.Fatalf("test %q should have not failed: %v", e.name, err)
}
if err != nil && !e.ok && err != ErrIncompatibleKey {
t.Fatalf("unexpected error type for %q: %v", e.name, err)
}
}
}
func testSealOpen(t *testing.T, prefixByte PrefixByte) {
kp, err := CreatePair(prefixByte)
if err != nil {
t.Fatalf("Failed to create pair for %v", prefixByte)
}
if kp == nil {
t.Fatalf("Failed to create pair for %v - nil keypair", prefixByte)
}
_, err = kp.Open([]byte("hello"), "ME")
if err == nil {
t.Fatalf("Expected Open to fail for %v", prefixByte)
}
if err != ErrInvalidNKeyOperation {
t.Fatalf("Expected Open to fail for %v with %v: %v", prefixByte, ErrInvalidNKeyOperation, err)
}
_, err = kp.Seal([]byte("hello"), "ME")
if err == nil {
t.Fatalf("Expected Seal to fail for %v", prefixByte)
}
if err != ErrInvalidNKeyOperation {
t.Fatalf("Expected Seal to fail for %v with %v: %v", prefixByte, ErrInvalidNKeyOperation, err)
}
_, err = kp.SealWithRand([]byte("hello"), "ME", nil)
if err == nil {
t.Fatalf("Expected SealWithRand to fail for %v", prefixByte)
}
if err != ErrInvalidNKeyOperation {
t.Fatalf("Expected SealWithRand to fail for %v with %v: %v", prefixByte, ErrInvalidNKeyOperation, err)
}
}
func TestSealOpen(t *testing.T) {
testSealOpen(t, PrefixByteOperator)
testSealOpen(t, PrefixByteAccount)
testSealOpen(t, PrefixByteUser)
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。