From c75329aaad72e868b57cdc969327173826e54ec1 Mon Sep 17 00:00:00 2001 From: Stephen Asbury Date: Tue, 4 Dec 2018 10:46:24 -0800 Subject: [PATCH] Isolate base64 codec (#22) * isolated all calls to encode base64 raw url encoding --- claims.go | 16 ++++++++++++---- decoder_test.go | 17 ++++++++++++++--- header.go | 3 +-- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/claims.go b/claims.go index e060a7d..ae21e99 100644 --- a/claims.go +++ b/claims.go @@ -63,12 +63,20 @@ type Prefix struct { nkeys.PrefixByte } +func encodeToString(d []byte) string { + return base64.RawURLEncoding.EncodeToString(d) +} + +func decodeString(s string) ([]byte, error) { + return base64.RawURLEncoding.DecodeString(s) +} + func serialize(v interface{}) (string, error) { j, err := json.Marshal(v) if err != nil { return "", err } - return base64.RawURLEncoding.EncodeToString(j), nil + return encodeToString(j), nil } func (c *ClaimsData) doEncode(header *Header, kp nkeys.KeyPair, claim Claims) (string, error) { @@ -143,7 +151,7 @@ func (c *ClaimsData) doEncode(header *Header, kp nkeys.KeyPair, claim Claims) (s if err != nil { return "", err } - eSig := base64.RawURLEncoding.EncodeToString(sig) + eSig := encodeToString(sig) return fmt.Sprintf("%s.%s.%s", h, payload, eSig), nil } @@ -173,7 +181,7 @@ func (c *ClaimsData) String(claim interface{}) string { } func parseClaims(s string, target Claims) error { - h, err := base64.RawURLEncoding.DecodeString(s) + h, err := decodeString(s) if err != nil { return err } @@ -239,7 +247,7 @@ func Decode(token string, target Claims) error { return err } - sig, err := base64.RawURLEncoding.DecodeString(chunks[2]) + sig, err := decodeString(chunks[2]) if err != nil { return err } diff --git a/decoder_test.go b/decoder_test.go index be6ff5a..6a8b0b4 100644 --- a/decoder_test.go +++ b/decoder_test.go @@ -1,7 +1,6 @@ package jwt import ( - "encoding/base64" "encoding/json" "fmt" "reflect" @@ -299,7 +298,7 @@ func TestBadClaimsEncoding(t *testing.T) { } func TestBadHeaderJSON(t *testing.T) { - payload := base64.RawURLEncoding.EncodeToString([]byte("{foo: bar}")) + payload := encodeToString([]byte("{foo: bar}")) _, err := parseHeaders(payload) if err == nil { t.Fatal("should have failed bad json") @@ -307,7 +306,7 @@ func TestBadHeaderJSON(t *testing.T) { } func TestBadClaimsJSON(t *testing.T) { - payload := base64.RawURLEncoding.EncodeToString([]byte("{foo: bar}")) + payload := encodeToString([]byte("{foo: bar}")) c := GenericClaims{} err := parseClaims(payload, &c) if err == nil { @@ -376,3 +375,15 @@ func TestDoEncodeNilKeyPair(t *testing.T) { t.Fatalf("unexpected error on encode: %v", err) } } + +// if this fails, the URL decoder was changed and JWTs will flap +func TestUsingURLDecoder(t *testing.T) { + token := "eyJ0eXAiOiJqd3QiLCJhbGciOiJlZDI1NTE5In0.eyJqdGkiOiJGQ1lZRjJLR0EzQTZHTlZQR0pIVjNUSExYR1VZWkFUREZLV1JTT1czUUo1T0k3QlJST0ZRIiwiaWF0IjoxNTQzOTQzNjc1LCJpc3MiOiJBQ1NKWkhOWlI0QUFUVE1KNzdUV1JONUJHVUZFWFhUS0gzWEtGTldDRkFCVzJRWldOUTRDQkhRRSIsInN1YiI6IkFEVEFHWVZYRkpPRENRM0g0VUZQQU43R1dXWk1BVU9FTTJMMkRWQkFWVFdLM01TU0xUS1JUTzVGIiwidHlwZSI6ImFjdGl2YXRpb24iLCJuYXRzIjp7InN1YmplY3QiOiJmb28iLCJ0eXBlIjoic2VydmljZSJ9fQ.HCZTCF-7wolS3Wjx3swQWMkoDhoo_4gp9EsuM5diJfZrH8s6NTpO0iT7_fKZm7dNDeEoqjwU--3ebp8j-Mm_Aw" + ac, err := DecodeActivationClaims(token) + if err != nil { + t.Fatal("shouldn't have failed to decode", err) + } + if ac == nil { + t.Fatal("should have returned activation") + } +} diff --git a/header.go b/header.go index 72ffd8f..ed07ee2 100644 --- a/header.go +++ b/header.go @@ -1,7 +1,6 @@ package jwt import ( - "encoding/base64" "encoding/json" "fmt" "strings" @@ -28,7 +27,7 @@ type Header struct { // Parses a header JWT token func parseHeaders(s string) (*Header, error) { - h, err := base64.RawURLEncoding.DecodeString(s) + h, err := decodeString(s) if err != nil { return nil, err }