Skip to content

Commit

Permalink
Change to RawURLEncoding
Browse files Browse the repository at this point in the history
Signed-off-by: Derek Collison <derek@nats.io>
  • Loading branch information
derekcollison committed Nov 30, 2018
1 parent 2a19de7 commit e2ce2c0
Show file tree
Hide file tree
Showing 11 changed files with 94 additions and 88 deletions.
4 changes: 2 additions & 2 deletions server/accounts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1228,7 +1228,7 @@ func TestAccountMapsUsers(t *testing.T) {
if err != nil {
t.Fatalf("Failed signing nonce: %v", err)
}
sig := base64.StdEncoding.EncodeToString(sigraw)
sig := base64.RawURLEncoding.EncodeToString(sigraw)

// PING needed to flush the +OK to us.
cs := fmt.Sprintf("CONNECT {\"nkey\":%q,\"sig\":\"%s\",\"verbose\":true,\"pedantic\":true}\r\nPING\r\n", pubKey, sig)
Expand Down Expand Up @@ -1258,7 +1258,7 @@ func TestAccountMapsUsers(t *testing.T) {
if err != nil {
t.Fatalf("Failed signing nonce: %v", err)
}
sig = base64.StdEncoding.EncodeToString(sigraw)
sig = base64.RawURLEncoding.EncodeToString(sigraw)

// PING needed to flush the +OK to us.
cs = fmt.Sprintf("CONNECT {\"nkey\":%q,\"sig\":\"%s\",\"verbose\":true,\"pedantic\":true}\r\nPING\r\n", pubKey, sig)
Expand Down
4 changes: 2 additions & 2 deletions server/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ func (s *Server) isClientAuthorized(c *client) bool {
c.Debugf("Signature missing")
return false
}
sig, err := base64.StdEncoding.DecodeString(c.opts.Sig)
sig, err := base64.RawURLEncoding.DecodeString(c.opts.Sig)
if err != nil {
c.Debugf("Signature not valid base64")
return false
Expand Down Expand Up @@ -366,7 +366,7 @@ func (s *Server) isClientAuthorized(c *client) bool {
c.Debugf("Signature missing")
return false
}
sig, err := base64.StdEncoding.DecodeString(c.opts.Sig)
sig, err := base64.RawURLEncoding.DecodeString(c.opts.Sig)
if err != nil {
c.Debugf("Signature not valid base64")
return false
Expand Down
4 changes: 2 additions & 2 deletions server/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -1543,7 +1543,7 @@ func (s *Server) endSubjectNoInterestForGateways(accName string, sub *subscripti
subjects := subjectsa[:0]
// Check that we had sent a no-interest on this account/subject.
c.mu.Lock()
if sni, _ := c.gw.sentNoInterest[accName]; sni != nil {
if sni := c.gw.sentNoInterest[accName]; sni != nil {
// For wildcard subjects, we look for the subjects
// this subscription is matching.
if hasWc {
Expand Down Expand Up @@ -1789,7 +1789,7 @@ func (c *client) processInboundGatewayMsg(msg []byte) {
// for that account/subject, so that if later there is a subscription on
// this subject, we need to send an R+ to remote gateways.
c.mu.Lock()
sni, _ := c.gw.sentNoInterest[string(c.pa.account)]
sni := c.gw.sentNoInterest[string(c.pa.account)]
if sni == nil {
sni = make(map[string]struct{})
sni[string(c.pa.subject)] = struct{}{}
Expand Down
109 changes: 64 additions & 45 deletions server/jwt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,7 @@ import (
"github.com/nats-io/nkeys"
)

const (
uJWT = "eyJ0eXAiOiJqd3QiLCJhbGciOiJlZDI1NTE5In0.eyJqdGkiOiJRVzRWWktISEJCUkFaSkFWREg3UjVDSk1RQ1pHWDZJM1FJWEJSMkdWSjRHSVRMRlJRMlpBIiwiaWF0IjoxNTQyMzg1NjMxLCJpc3MiOiJBQ1E1VkpLS1dEM0s1QzdSVkFFMjJNT1hESkFNTEdFTUZJM1NDR1JWUlpKSlFUTU9QTjMzQlhVSyIsIm5hbWUiOiJkZXJlayIsInN1YiI6IlVEMkZMTEdGRVJRVlFRM1NCS09OTkcyUU1JTVRaUUtLTFRVM0FWRzVJM0VRRUZIQlBHUEUyWFFTIiwidHlwZSI6InVzZXIiLCJuYXRzIjp7InB1YiI6e30sInN1YiI6e319fQ.6PmFNn3x0AH3V05oemO28riP63+QTvk9g/Qtt6wBcXJqgW6YSVxk6An1MjvTn1tH7S9tJ0zOIGp7/OLjP1tbBQ"
aJWT = "eyJ0eXAiOiJqd3QiLCJhbGciOiJlZDI1NTE5In0.eyJqdGkiOiJJSTdKSU5JUENVWTZEU1JDSUpZT1daR0k0UlRGNUdCNjVZUUtSNE9RVlBCQlpBNFhCQlhRIiwiaWF0IjoxNTQyMzMxNzgwLCJpc3MiOiJPRDJXMkk0TVZSQTVUR1pMWjJBRzZaSEdWTDNPVEtGV1FKRklYNFROQkVSMjNFNlA0NlMzNDVZWSIsIm5hbWUiOiJmb28iLCJzdWIiOiJBQ1E1VkpLS1dEM0s1QzdSVkFFMjJNT1hESkFNTEdFTUZJM1NDR1JWUlpKSlFUTU9QTjMzQlhVSyIsInR5cGUiOiJhY2NvdW50IiwibmF0cyI6e319.Dg2A1NCJWvXhBQZN9QNHAq1KqsFIKxzLhYvD5yH0DYZPC0gXtdhLkwJ5uiooki6YvzR8UNQZ9XuWgDpNpwryDg"
)

var (
uSeed = []byte("SUAIO3FHUX5PNV2LQIIP7TZ3N4L7TX3W53MQGEIVYFIGA635OZCKEYHFLM")
oSeed = []byte("SOAL7GTNI66CTVVNXBNQMG6V2HTDRWC3HGEP7D2OUTWNWSNYZDXWFOX4SU")
aSeed = []byte("SAANRM6JVDEYZTR6DXCWUSDDJHGOHAFITXEQBSEZSY5JENTDVRZ6WNKTTY")
)
Expand All @@ -49,10 +43,7 @@ func opTrustBasicSetup() *Server {
}

func buildMemAccResolver(s *Server) {
kp, _ := nkeys.FromSeed(aSeed)
pub, _ := kp.PublicKey()
mr := &MemAccResolver{}
mr.Store(pub, aJWT)
s.mu.Lock()
s.accResolver = mr
s.mu.Unlock()
Expand All @@ -79,7 +70,7 @@ func createClient(t *testing.T, s *Server, akp nkeys.KeyPair) (*client, *bufio.R
var info nonceInfo
json.Unmarshal([]byte(l[5:]), &info)
sigraw, _ := nkp.Sign([]byte(info.Nonce))
sig := base64.StdEncoding.EncodeToString(sigraw)
sig := base64.RawURLEncoding.EncodeToString(sigraw)

cs := fmt.Sprintf("CONNECT {\"jwt\":%q,\"sig\":\"%s\"}\r\nPING\r\n", ujwt, sig)
return c, cr, cs
Expand Down Expand Up @@ -123,11 +114,21 @@ func TestJWTUser(t *testing.T) {
t.Fatalf("Expected an error")
}

c, cr, _ = newClientForServer(s)
okp, _ := nkeys.FromSeed(oSeed)

// Create an account that will be expired.
akp, _ := nkeys.CreateAccount()
apub, _ := akp.PublicKey()
nac := jwt.NewAccountClaims(apub)
ajwt, err := nac.Encode(okp)
if err != nil {
t.Fatalf("Error generating account JWT: %v", err)
}

c, cr, cs := createClient(t, s, akp)

// PING needed to flush the +OK/-ERR to us.
// This should fail too since no account resolver is defined.
cs := fmt.Sprintf("CONNECT {\"jwt\":%q,\"sig\":\"%s\",\"verbose\":true,\"pedantic\":true}\r\nPING\r\n", uJWT, "xxx")
go c.parse([]byte(cs))
l, _ = cr.ReadString('\n')
if !strings.HasPrefix(l, "-ERR ") {
Expand All @@ -137,24 +138,14 @@ func TestJWTUser(t *testing.T) {
// Ok now let's walk through and make sure all is good.
// We will set the account resolver by hand to a memory resolver.
buildMemAccResolver(s)
addAccountToMemResolver(s, apub, ajwt)

c, cr, l = newClientForServer(s)

// Sign Nonce
kp, _ := nkeys.FromSeed(uSeed)

var info nonceInfo
json.Unmarshal([]byte(l[5:]), &info)
sigraw, _ := kp.Sign([]byte(info.Nonce))
sig := base64.StdEncoding.EncodeToString(sigraw)
c, cr, cs = createClient(t, s, akp)

// PING needed to flush the +OK/-ERR to us.
// This should fail too since no account resolver is defined.
cs = fmt.Sprintf("CONNECT {\"jwt\":%q,\"sig\":\"%s\",\"verbose\":true,\"pedantic\":true}\r\nPING\r\n", uJWT, sig)
go c.parse([]byte(cs))
l, _ = cr.ReadString('\n')
if !strings.HasPrefix(l, "+OK") {
t.Fatalf("Expected an OK, got: %v", l)
if !strings.HasPrefix(l, "PONG") {
t.Fatalf("Expected a PONG, got %q", l)
}
}

Expand All @@ -173,36 +164,44 @@ func TestJWTUserBadTrusted(t *testing.T) {

buildMemAccResolver(s)

c, cr, l := newClientForServer(s)

// Sign Nonce
kp, _ := nkeys.FromSeed(uSeed)
okp, _ := nkeys.FromSeed(oSeed)

var info nonceInfo
json.Unmarshal([]byte(l[5:]), &info)
sigraw, _ := kp.Sign([]byte(info.Nonce))
sig := base64.StdEncoding.EncodeToString(sigraw)
// Create an account that will be expired.
akp, _ := nkeys.CreateAccount()
apub, _ := akp.PublicKey()
nac := jwt.NewAccountClaims(apub)
ajwt, err := nac.Encode(okp)
if err != nil {
t.Fatalf("Error generating account JWT: %v", err)
}
addAccountToMemResolver(s, apub, ajwt)

// PING needed to flush the +OK/-ERR to us.
// This should fail too since no account resolver is defined.
cs := fmt.Sprintf("CONNECT {\"jwt\":%q,\"sig\":\"%s\",\"verbose\":true,\"pedantic\":true}\r\nPING\r\n", uJWT, sig)
c, cr, cs := createClient(t, s, akp)
go c.parse([]byte(cs))
l, _ = cr.ReadString('\n')
l, _ := cr.ReadString('\n')
if !strings.HasPrefix(l, "-ERR ") {
t.Fatalf("Expected an error")
}
}

// Test that if a user tries to connect with an expired user JWT we do the right thing.
func TestJWTUserExpired(t *testing.T) {
okp, _ := nkeys.FromSeed(oSeed)

akp, _ := nkeys.CreateAccount()
apub, _ := akp.PublicKey()
nac := jwt.NewAccountClaims(apub)
ajwt, err := nac.Encode(okp)
if err != nil {
t.Fatalf("Error generating account JWT: %v", err)
}

// Create a new user that we will make sure has expired.
nkp, _ := nkeys.CreateUser()
pub, _ := nkp.PublicKey()
nuc := jwt.NewUserClaims(pub)
nuc.IssuedAt = time.Now().Add(-10 * time.Second).Unix()
nuc.Expires = time.Now().Add(-2 * time.Second).Unix()

akp, _ := nkeys.FromSeed(aSeed)
jwt, err := nuc.Encode(akp)
if err != nil {
t.Fatalf("Error generating user JWT: %v", err)
Expand All @@ -211,14 +210,15 @@ func TestJWTUserExpired(t *testing.T) {
s := opTrustBasicSetup()
defer s.Shutdown()
buildMemAccResolver(s)
addAccountToMemResolver(s, apub, ajwt)

c, cr, l := newClientForServer(s)

// Sign Nonce
var info nonceInfo
json.Unmarshal([]byte(l[5:]), &info)
sigraw, _ := nkp.Sign([]byte(info.Nonce))
sig := base64.StdEncoding.EncodeToString(sigraw)
sig := base64.RawURLEncoding.EncodeToString(sigraw)

// PING needed to flush the +OK/-ERR to us.
// This should fail too since no account resolver is defined.
Expand All @@ -231,14 +231,22 @@ func TestJWTUserExpired(t *testing.T) {
}

func TestJWTUserExpiresAfterConnect(t *testing.T) {
okp, _ := nkeys.FromSeed(oSeed)

akp, _ := nkeys.CreateAccount()
apub, _ := akp.PublicKey()
nac := jwt.NewAccountClaims(apub)
ajwt, err := nac.Encode(okp)
if err != nil {
t.Fatalf("Error generating account JWT: %v", err)
}

// Create a new user that we will make sure has expired.
nkp, _ := nkeys.CreateUser()
pub, _ := nkp.PublicKey()
nuc := jwt.NewUserClaims(pub)
nuc.IssuedAt = time.Now().Unix()
nuc.Expires = time.Now().Add(time.Second).Unix()

akp, _ := nkeys.FromSeed(aSeed)
jwt, err := nuc.Encode(akp)
if err != nil {
t.Fatalf("Error generating user JWT: %v", err)
Expand All @@ -247,14 +255,15 @@ func TestJWTUserExpiresAfterConnect(t *testing.T) {
s := opTrustBasicSetup()
defer s.Shutdown()
buildMemAccResolver(s)
addAccountToMemResolver(s, apub, ajwt)

c, cr, l := newClientForServer(s)

// Sign Nonce
var info nonceInfo
json.Unmarshal([]byte(l[5:]), &info)
sigraw, _ := nkp.Sign([]byte(info.Nonce))
sig := base64.StdEncoding.EncodeToString(sigraw)
sig := base64.RawURLEncoding.EncodeToString(sigraw)

// PING needed to flush the +OK/-ERR to us.
// This should fail too since no account resolver is defined.
Expand Down Expand Up @@ -283,6 +292,8 @@ func TestJWTUserExpiresAfterConnect(t *testing.T) {
}

func TestJWTUserPermissionClaims(t *testing.T) {
okp, _ := nkeys.FromSeed(oSeed)

nkp, _ := nkeys.CreateUser()
pub, _ := nkp.PublicKey()
nuc := jwt.NewUserClaims(pub)
Expand All @@ -295,6 +306,13 @@ func TestJWTUserPermissionClaims(t *testing.T) {
nuc.Permissions.Sub.Deny.Add("baz")

akp, _ := nkeys.FromSeed(aSeed)
apub, _ := akp.PublicKey()
nac := jwt.NewAccountClaims(apub)
ajwt, err := nac.Encode(okp)
if err != nil {
t.Fatalf("Error generating account JWT: %v", err)
}

jwt, err := nuc.Encode(akp)
if err != nil {
t.Fatalf("Error generating user JWT: %v", err)
Expand All @@ -303,14 +321,15 @@ func TestJWTUserPermissionClaims(t *testing.T) {
s := opTrustBasicSetup()
defer s.Shutdown()
buildMemAccResolver(s)
addAccountToMemResolver(s, apub, ajwt)

c, cr, l := newClientForServer(s)

// Sign Nonce
var info nonceInfo
json.Unmarshal([]byte(l[5:]), &info)
sigraw, _ := nkp.Sign([]byte(info.Nonce))
sig := base64.StdEncoding.EncodeToString(sigraw)
sig := base64.RawURLEncoding.EncodeToString(sigraw)

// PING needed to flush the +OK/-ERR to us.
// This should fail too since no account resolver is defined.
Expand Down
4 changes: 2 additions & 2 deletions server/nkey.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
// Raw length of the nonce challenge
const (
nonceRawLen = 11
nonceLen = 16 // base64.StdEncoding.EncodedLen(nonceRawLen)
nonceLen = 15 // base64.RawURLEncoding.EncodedLen(nonceRawLen)
)

// nonceRequired tells us if we should send a nonce.
Expand All @@ -38,5 +38,5 @@ func (s *Server) generateNonce(n []byte) {
var raw [nonceRawLen]byte
data := raw[:]
s.prand.Read(data)
base64.StdEncoding.Encode(n, data)
base64.RawURLEncoding.Encode(n, data)
}
8 changes: 4 additions & 4 deletions server/nkey_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ func TestNkeyClientConnect(t *testing.T) {
if err != nil {
t.Fatalf("Failed signing nonce: %v", err)
}
sig := base64.StdEncoding.EncodeToString(sigraw)
sig := base64.RawURLEncoding.EncodeToString(sigraw)

// PING needed to flush the +OK to us.
cs = fmt.Sprintf("CONNECT {\"nkey\":%q,\"sig\":\"%s\",\"verbose\":true,\"pedantic\":true}\r\nPING\r\n", pubKey, sig)
Expand Down Expand Up @@ -187,7 +187,7 @@ func TestMixedClientConnect(t *testing.T) {
if err != nil {
t.Fatalf("Failed signing nonce: %v", err)
}
sig := base64.StdEncoding.EncodeToString(sigraw)
sig := base64.RawURLEncoding.EncodeToString(sigraw)

// PING needed to flush the +OK to us.
cs := fmt.Sprintf("CONNECT {\"nkey\":%q,\"sig\":\"%s\",\"verbose\":true,\"pedantic\":true}\r\nPING\r\n", pubKey, sig)
Expand Down Expand Up @@ -240,15 +240,15 @@ func BenchmarkNonceGeneration(b *testing.B) {
prand := mrand.New(mrand.NewSource(time.Now().UnixNano()))
for i := 0; i < b.N; i++ {
prand.Read(data)
base64.StdEncoding.Encode(b64, data)
base64.RawURLEncoding.Encode(b64, data)
}
}

func BenchmarkPublicVerify(b *testing.B) {
data := make([]byte, nonceRawLen)
nonce := make([]byte, nonceLen)
mrand.Read(data)
base64.StdEncoding.Encode(nonce, data)
base64.RawURLEncoding.Encode(nonce, data)

user, err := nkeys.CreateUser()
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions server/reload_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2770,7 +2770,7 @@ func TestConfigReloadAccountNKeyUsers(t *testing.T) {
if err != nil {
t.Fatalf("Failed signing nonce: %v", err)
}
sig := base64.StdEncoding.EncodeToString(sigraw)
sig := base64.RawURLEncoding.EncodeToString(sigraw)

// PING needed to flush the +OK to us.
cs := fmt.Sprintf("CONNECT {\"nkey\":%q,\"sig\":\"%s\",\"verbose\":true,\"pedantic\":true}\r\nPING\r\n", pubKey, sig)
Expand Down Expand Up @@ -2800,7 +2800,7 @@ func TestConfigReloadAccountNKeyUsers(t *testing.T) {
if err != nil {
t.Fatalf("Failed signing nonce: %v", err)
}
sig = base64.StdEncoding.EncodeToString(sigraw)
sig = base64.RawURLEncoding.EncodeToString(sigraw)

// PING needed to flush the +OK to us.
cs = fmt.Sprintf("CONNECT {\"nkey\":%q,\"sig\":\"%s\",\"verbose\":true,\"pedantic\":true}\r\nPING\r\n", pubKey, sig)
Expand Down
Loading

0 comments on commit e2ce2c0

Please sign in to comment.