Split non-cipher code to utils.go out of ciphers.go
This commit is contained in:
		
							parent
							
								
									ce2e92bc57
								
							
						
					
					
						commit
						f60e24d9c3
					
				|  | @ -3,112 +3,12 @@ package encryption | ||||||
| import ( | import ( | ||||||
| 	"crypto/aes" | 	"crypto/aes" | ||||||
| 	"crypto/cipher" | 	"crypto/cipher" | ||||||
| 	"crypto/hmac" |  | ||||||
| 	"crypto/rand" | 	"crypto/rand" | ||||||
| 	"crypto/sha1" |  | ||||||
| 	"crypto/sha256" |  | ||||||
| 	"encoding/base64" | 	"encoding/base64" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"hash" |  | ||||||
| 	"io" | 	"io" | ||||||
| 	"net/http" |  | ||||||
| 	"strconv" |  | ||||||
| 	"strings" |  | ||||||
| 	"time" |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // SecretBytes attempts to base64 decode the secret, if that fails it treats the secret as binary
 |  | ||||||
| func SecretBytes(secret string) []byte { |  | ||||||
| 	b, err := base64.RawURLEncoding.DecodeString(strings.TrimRight(secret, "=")) |  | ||||||
| 	if err == nil { |  | ||||||
| 		// Only return decoded form if a valid AES length
 |  | ||||||
| 		// Don't want unintentional decoding resulting in invalid lengths confusing a user
 |  | ||||||
| 		// that thought they used a 16, 24, 32 length string
 |  | ||||||
| 		for _, i := range []int{16, 24, 32} { |  | ||||||
| 			if len(b) == i { |  | ||||||
| 				return b |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	// If decoding didn't work or resulted in non-AES compliant length,
 |  | ||||||
| 	// assume the raw string was the intended secret
 |  | ||||||
| 	return []byte(secret) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // cookies are stored in a 3 part (value + timestamp + signature) to enforce that the values are as originally set.
 |  | ||||||
| // additionally, the 'value' is encrypted so it's opaque to the browser
 |  | ||||||
| 
 |  | ||||||
| // Validate ensures a cookie is properly signed
 |  | ||||||
| func Validate(cookie *http.Cookie, seed string, expiration time.Duration) (value []byte, t time.Time, ok bool) { |  | ||||||
| 	// value, timestamp, sig
 |  | ||||||
| 	parts := strings.Split(cookie.Value, "|") |  | ||||||
| 	if len(parts) != 3 { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	if checkSignature(parts[2], seed, cookie.Name, parts[0], parts[1]) { |  | ||||||
| 		ts, err := strconv.Atoi(parts[1]) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		// The expiration timestamp set when the cookie was created
 |  | ||||||
| 		// isn't sent back by the browser. Hence, we check whether the
 |  | ||||||
| 		// creation timestamp stored in the cookie falls within the
 |  | ||||||
| 		// window defined by (Now()-expiration, Now()].
 |  | ||||||
| 		t = time.Unix(int64(ts), 0) |  | ||||||
| 		if t.After(time.Now().Add(expiration*-1)) && t.Before(time.Now().Add(time.Minute*5)) { |  | ||||||
| 			// it's a valid cookie. now get the contents
 |  | ||||||
| 			rawValue, err := base64.URLEncoding.DecodeString(parts[0]) |  | ||||||
| 			if err == nil { |  | ||||||
| 				value = rawValue |  | ||||||
| 				ok = true |  | ||||||
| 				return |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // SignedValue returns a cookie that is signed and can later be checked with Validate
 |  | ||||||
| func SignedValue(seed string, key string, value []byte, now time.Time) string { |  | ||||||
| 	encodedValue := base64.URLEncoding.EncodeToString(value) |  | ||||||
| 	timeStr := fmt.Sprintf("%d", now.Unix()) |  | ||||||
| 	sig := cookieSignature(sha256.New, seed, key, encodedValue, timeStr) |  | ||||||
| 	cookieVal := fmt.Sprintf("%s|%s|%s", encodedValue, timeStr, sig) |  | ||||||
| 	return cookieVal |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func cookieSignature(signer func() hash.Hash, args ...string) string { |  | ||||||
| 	h := hmac.New(signer, []byte(args[0])) |  | ||||||
| 	for _, arg := range args[1:] { |  | ||||||
| 		h.Write([]byte(arg)) |  | ||||||
| 	} |  | ||||||
| 	var b []byte |  | ||||||
| 	b = h.Sum(b) |  | ||||||
| 	return base64.URLEncoding.EncodeToString(b) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func checkSignature(signature string, args ...string) bool { |  | ||||||
| 	checkSig := cookieSignature(sha256.New, args...) |  | ||||||
| 	if checkHmac(signature, checkSig) { |  | ||||||
| 		return true |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// TODO: After appropriate rollout window, remove support for SHA1
 |  | ||||||
| 	legacySig := cookieSignature(sha1.New, args...) |  | ||||||
| 	return checkHmac(signature, legacySig) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func checkHmac(input, expected string) bool { |  | ||||||
| 	inputMAC, err1 := base64.URLEncoding.DecodeString(input) |  | ||||||
| 	if err1 == nil { |  | ||||||
| 		expectedMAC, err2 := base64.URLEncoding.DecodeString(expected) |  | ||||||
| 		if err2 == nil { |  | ||||||
| 			return hmac.Equal(inputMAC, expectedMAC) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return false |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Cipher provides methods to encrypt and decrypt
 | // Cipher provides methods to encrypt and decrypt
 | ||||||
| type Cipher interface { | type Cipher interface { | ||||||
| 	Encrypt(value []byte) ([]byte, error) | 	Encrypt(value []byte) ([]byte, error) | ||||||
|  |  | ||||||
|  | @ -2,103 +2,13 @@ package encryption | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"crypto/rand" | 	"crypto/rand" | ||||||
| 	"crypto/sha1" |  | ||||||
| 	"crypto/sha256" |  | ||||||
| 	"encoding/base64" | 	"encoding/base64" | ||||||
| 	"fmt" |  | ||||||
| 	"io" | 	"io" | ||||||
| 	"testing" | 	"testing" | ||||||
| 
 | 
 | ||||||
| 	"github.com/stretchr/testify/assert" | 	"github.com/stretchr/testify/assert" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func TestSecretBytesEncoded(t *testing.T) { |  | ||||||
| 	for _, secretSize := range []int{16, 24, 32} { |  | ||||||
| 		t.Run(fmt.Sprintf("%d", secretSize), func(t *testing.T) { |  | ||||||
| 			secret := make([]byte, secretSize) |  | ||||||
| 			_, err := io.ReadFull(rand.Reader, secret) |  | ||||||
| 			assert.Equal(t, nil, err) |  | ||||||
| 
 |  | ||||||
| 			// We test both padded & raw Base64 to ensure we handle both
 |  | ||||||
| 			// potential user input routes for Base64
 |  | ||||||
| 			base64Padded := base64.URLEncoding.EncodeToString(secret) |  | ||||||
| 			sb := SecretBytes(base64Padded) |  | ||||||
| 			assert.Equal(t, secret, sb) |  | ||||||
| 			assert.Equal(t, len(sb), secretSize) |  | ||||||
| 
 |  | ||||||
| 			base64Raw := base64.RawURLEncoding.EncodeToString(secret) |  | ||||||
| 			sb = SecretBytes(base64Raw) |  | ||||||
| 			assert.Equal(t, secret, sb) |  | ||||||
| 			assert.Equal(t, len(sb), secretSize) |  | ||||||
| 		}) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // A string that isn't intended as Base64 and still decodes (but to unintended length)
 |  | ||||||
| // will return the original secret as bytes
 |  | ||||||
| func TestSecretBytesEncodedWrongSize(t *testing.T) { |  | ||||||
| 	for _, secretSize := range []int{15, 20, 28, 33, 44} { |  | ||||||
| 		t.Run(fmt.Sprintf("%d", secretSize), func(t *testing.T) { |  | ||||||
| 			secret := make([]byte, secretSize) |  | ||||||
| 			_, err := io.ReadFull(rand.Reader, secret) |  | ||||||
| 			assert.Equal(t, nil, err) |  | ||||||
| 
 |  | ||||||
| 			// We test both padded & raw Base64 to ensure we handle both
 |  | ||||||
| 			// potential user input routes for Base64
 |  | ||||||
| 			base64Padded := base64.URLEncoding.EncodeToString(secret) |  | ||||||
| 			sb := SecretBytes(base64Padded) |  | ||||||
| 			assert.NotEqual(t, secret, sb) |  | ||||||
| 			assert.NotEqual(t, len(sb), secretSize) |  | ||||||
| 			// The given secret is returned as []byte
 |  | ||||||
| 			assert.Equal(t, base64Padded, string(sb)) |  | ||||||
| 
 |  | ||||||
| 			base64Raw := base64.RawURLEncoding.EncodeToString(secret) |  | ||||||
| 			sb = SecretBytes(base64Raw) |  | ||||||
| 			assert.NotEqual(t, secret, sb) |  | ||||||
| 			assert.NotEqual(t, len(sb), secretSize) |  | ||||||
| 			// The given secret is returned as []byte
 |  | ||||||
| 			assert.Equal(t, base64Raw, string(sb)) |  | ||||||
| 		}) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func TestSecretBytesNonBase64(t *testing.T) { |  | ||||||
| 	trailer := "equals==========" |  | ||||||
| 	assert.Equal(t, trailer, string(SecretBytes(trailer))) |  | ||||||
| 
 |  | ||||||
| 	raw16 := "asdflkjhqwer)(*&" |  | ||||||
| 	sb16 := SecretBytes(raw16) |  | ||||||
| 	assert.Equal(t, raw16, string(sb16)) |  | ||||||
| 	assert.Equal(t, 16, len(sb16)) |  | ||||||
| 
 |  | ||||||
| 	raw24 := "asdflkjhqwer)(*&CJEN#$%^" |  | ||||||
| 	sb24 := SecretBytes(raw24) |  | ||||||
| 	assert.Equal(t, raw24, string(sb24)) |  | ||||||
| 	assert.Equal(t, 24, len(sb24)) |  | ||||||
| 
 |  | ||||||
| 	raw32 := "asdflkjhqwer)(*&1234lkjhqwer)(*&" |  | ||||||
| 	sb32 := SecretBytes(raw32) |  | ||||||
| 	assert.Equal(t, raw32, string(sb32)) |  | ||||||
| 	assert.Equal(t, 32, len(sb32)) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func TestSignAndValidate(t *testing.T) { |  | ||||||
| 	seed := "0123456789abcdef" |  | ||||||
| 	key := "cookie-name" |  | ||||||
| 	value := base64.URLEncoding.EncodeToString([]byte("I am soooo encoded")) |  | ||||||
| 	epoch := "123456789" |  | ||||||
| 
 |  | ||||||
| 	sha256sig := cookieSignature(sha256.New, seed, key, value, epoch) |  | ||||||
| 	sha1sig := cookieSignature(sha1.New, seed, key, value, epoch) |  | ||||||
| 
 |  | ||||||
| 	assert.True(t, checkSignature(sha256sig, seed, key, value, epoch)) |  | ||||||
| 	// This should be switched to False after fully deprecating SHA1
 |  | ||||||
| 	assert.True(t, checkSignature(sha1sig, seed, key, value, epoch)) |  | ||||||
| 
 |  | ||||||
| 	assert.False(t, checkSignature(sha256sig, seed, key, "tampered", epoch)) |  | ||||||
| 	assert.False(t, checkSignature(sha1sig, seed, key, "tampered", epoch)) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func TestEncodeAndDecodeAccessToken(t *testing.T) { | func TestEncodeAndDecodeAccessToken(t *testing.T) { | ||||||
| 	const secret = "0123456789abcdefghijklmnopqrstuv" | 	const secret = "0123456789abcdefghijklmnopqrstuv" | ||||||
| 	const token = "my access token" | 	const token = "my access token" | ||||||
|  |  | ||||||
|  | @ -0,0 +1,107 @@ | ||||||
|  | package encryption | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"crypto/hmac" | ||||||
|  | 	"crypto/sha1" | ||||||
|  | 	"crypto/sha256" | ||||||
|  | 	"encoding/base64" | ||||||
|  | 	"fmt" | ||||||
|  | 	"hash" | ||||||
|  | 	"net/http" | ||||||
|  | 	"strconv" | ||||||
|  | 	"strings" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // SecretBytes attempts to base64 decode the secret, if that fails it treats the secret as binary
 | ||||||
|  | func SecretBytes(secret string) []byte { | ||||||
|  | 	b, err := base64.RawURLEncoding.DecodeString(strings.TrimRight(secret, "=")) | ||||||
|  | 	if err == nil { | ||||||
|  | 		// Only return decoded form if a valid AES length
 | ||||||
|  | 		// Don't want unintentional decoding resulting in invalid lengths confusing a user
 | ||||||
|  | 		// that thought they used a 16, 24, 32 length string
 | ||||||
|  | 		for _, i := range []int{16, 24, 32} { | ||||||
|  | 			if len(b) == i { | ||||||
|  | 				return b | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	// If decoding didn't work or resulted in non-AES compliant length,
 | ||||||
|  | 	// assume the raw string was the intended secret
 | ||||||
|  | 	return []byte(secret) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // cookies are stored in a 3 part (value + timestamp + signature) to enforce that the values are as originally set.
 | ||||||
|  | // additionally, the 'value' is encrypted so it's opaque to the browser
 | ||||||
|  | 
 | ||||||
|  | // Validate ensures a cookie is properly signed
 | ||||||
|  | func Validate(cookie *http.Cookie, seed string, expiration time.Duration) (value []byte, t time.Time, ok bool) { | ||||||
|  | 	// value, timestamp, sig
 | ||||||
|  | 	parts := strings.Split(cookie.Value, "|") | ||||||
|  | 	if len(parts) != 3 { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	if checkSignature(parts[2], seed, cookie.Name, parts[0], parts[1]) { | ||||||
|  | 		ts, err := strconv.Atoi(parts[1]) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 		// The expiration timestamp set when the cookie was created
 | ||||||
|  | 		// isn't sent back by the browser. Hence, we check whether the
 | ||||||
|  | 		// creation timestamp stored in the cookie falls within the
 | ||||||
|  | 		// window defined by (Now()-expiration, Now()].
 | ||||||
|  | 		t = time.Unix(int64(ts), 0) | ||||||
|  | 		if t.After(time.Now().Add(expiration*-1)) && t.Before(time.Now().Add(time.Minute*5)) { | ||||||
|  | 			// it's a valid cookie. now get the contents
 | ||||||
|  | 			rawValue, err := base64.URLEncoding.DecodeString(parts[0]) | ||||||
|  | 			if err == nil { | ||||||
|  | 				value = rawValue | ||||||
|  | 				ok = true | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // SignedValue returns a cookie that is signed and can later be checked with Validate
 | ||||||
|  | func SignedValue(seed string, key string, value []byte, now time.Time) string { | ||||||
|  | 	encodedValue := base64.URLEncoding.EncodeToString(value) | ||||||
|  | 	timeStr := fmt.Sprintf("%d", now.Unix()) | ||||||
|  | 	sig := cookieSignature(sha256.New, seed, key, encodedValue, timeStr) | ||||||
|  | 	cookieVal := fmt.Sprintf("%s|%s|%s", encodedValue, timeStr, sig) | ||||||
|  | 	return cookieVal | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func cookieSignature(signer func() hash.Hash, args ...string) string { | ||||||
|  | 	h := hmac.New(signer, []byte(args[0])) | ||||||
|  | 	for _, arg := range args[1:] { | ||||||
|  | 		h.Write([]byte(arg)) | ||||||
|  | 	} | ||||||
|  | 	var b []byte | ||||||
|  | 	b = h.Sum(b) | ||||||
|  | 	return base64.URLEncoding.EncodeToString(b) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func checkSignature(signature string, args ...string) bool { | ||||||
|  | 	checkSig := cookieSignature(sha256.New, args...) | ||||||
|  | 	if checkHmac(signature, checkSig) { | ||||||
|  | 		return true | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// TODO: After appropriate rollout window, remove support for SHA1
 | ||||||
|  | 	legacySig := cookieSignature(sha1.New, args...) | ||||||
|  | 	return checkHmac(signature, legacySig) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func checkHmac(input, expected string) bool { | ||||||
|  | 	inputMAC, err1 := base64.URLEncoding.DecodeString(input) | ||||||
|  | 	if err1 == nil { | ||||||
|  | 		expectedMAC, err2 := base64.URLEncoding.DecodeString(expected) | ||||||
|  | 		if err2 == nil { | ||||||
|  | 			return hmac.Equal(inputMAC, expectedMAC) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @ -0,0 +1,100 @@ | ||||||
|  | package encryption | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"crypto/rand" | ||||||
|  | 	"crypto/sha1" | ||||||
|  | 	"crypto/sha256" | ||||||
|  | 	"encoding/base64" | ||||||
|  | 	"fmt" | ||||||
|  | 	"io" | ||||||
|  | 	"testing" | ||||||
|  | 
 | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func TestSecretBytesEncoded(t *testing.T) { | ||||||
|  | 	for _, secretSize := range []int{16, 24, 32} { | ||||||
|  | 		t.Run(fmt.Sprintf("%d", secretSize), func(t *testing.T) { | ||||||
|  | 			secret := make([]byte, secretSize) | ||||||
|  | 			_, err := io.ReadFull(rand.Reader, secret) | ||||||
|  | 			assert.Equal(t, nil, err) | ||||||
|  | 
 | ||||||
|  | 			// We test both padded & raw Base64 to ensure we handle both
 | ||||||
|  | 			// potential user input routes for Base64
 | ||||||
|  | 			base64Padded := base64.URLEncoding.EncodeToString(secret) | ||||||
|  | 			sb := SecretBytes(base64Padded) | ||||||
|  | 			assert.Equal(t, secret, sb) | ||||||
|  | 			assert.Equal(t, len(sb), secretSize) | ||||||
|  | 
 | ||||||
|  | 			base64Raw := base64.RawURLEncoding.EncodeToString(secret) | ||||||
|  | 			sb = SecretBytes(base64Raw) | ||||||
|  | 			assert.Equal(t, secret, sb) | ||||||
|  | 			assert.Equal(t, len(sb), secretSize) | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // A string that isn't intended as Base64 and still decodes (but to unintended length)
 | ||||||
|  | // will return the original secret as bytes
 | ||||||
|  | func TestSecretBytesEncodedWrongSize(t *testing.T) { | ||||||
|  | 	for _, secretSize := range []int{15, 20, 28, 33, 44} { | ||||||
|  | 		t.Run(fmt.Sprintf("%d", secretSize), func(t *testing.T) { | ||||||
|  | 			secret := make([]byte, secretSize) | ||||||
|  | 			_, err := io.ReadFull(rand.Reader, secret) | ||||||
|  | 			assert.Equal(t, nil, err) | ||||||
|  | 
 | ||||||
|  | 			// We test both padded & raw Base64 to ensure we handle both
 | ||||||
|  | 			// potential user input routes for Base64
 | ||||||
|  | 			base64Padded := base64.URLEncoding.EncodeToString(secret) | ||||||
|  | 			sb := SecretBytes(base64Padded) | ||||||
|  | 			assert.NotEqual(t, secret, sb) | ||||||
|  | 			assert.NotEqual(t, len(sb), secretSize) | ||||||
|  | 			// The given secret is returned as []byte
 | ||||||
|  | 			assert.Equal(t, base64Padded, string(sb)) | ||||||
|  | 
 | ||||||
|  | 			base64Raw := base64.RawURLEncoding.EncodeToString(secret) | ||||||
|  | 			sb = SecretBytes(base64Raw) | ||||||
|  | 			assert.NotEqual(t, secret, sb) | ||||||
|  | 			assert.NotEqual(t, len(sb), secretSize) | ||||||
|  | 			// The given secret is returned as []byte
 | ||||||
|  | 			assert.Equal(t, base64Raw, string(sb)) | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestSecretBytesNonBase64(t *testing.T) { | ||||||
|  | 	trailer := "equals==========" | ||||||
|  | 	assert.Equal(t, trailer, string(SecretBytes(trailer))) | ||||||
|  | 
 | ||||||
|  | 	raw16 := "asdflkjhqwer)(*&" | ||||||
|  | 	sb16 := SecretBytes(raw16) | ||||||
|  | 	assert.Equal(t, raw16, string(sb16)) | ||||||
|  | 	assert.Equal(t, 16, len(sb16)) | ||||||
|  | 
 | ||||||
|  | 	raw24 := "asdflkjhqwer)(*&CJEN#$%^" | ||||||
|  | 	sb24 := SecretBytes(raw24) | ||||||
|  | 	assert.Equal(t, raw24, string(sb24)) | ||||||
|  | 	assert.Equal(t, 24, len(sb24)) | ||||||
|  | 
 | ||||||
|  | 	raw32 := "asdflkjhqwer)(*&1234lkjhqwer)(*&" | ||||||
|  | 	sb32 := SecretBytes(raw32) | ||||||
|  | 	assert.Equal(t, raw32, string(sb32)) | ||||||
|  | 	assert.Equal(t, 32, len(sb32)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestSignAndValidate(t *testing.T) { | ||||||
|  | 	seed := "0123456789abcdef" | ||||||
|  | 	key := "cookie-name" | ||||||
|  | 	value := base64.URLEncoding.EncodeToString([]byte("I am soooo encoded")) | ||||||
|  | 	epoch := "123456789" | ||||||
|  | 
 | ||||||
|  | 	sha256sig := cookieSignature(sha256.New, seed, key, value, epoch) | ||||||
|  | 	sha1sig := cookieSignature(sha1.New, seed, key, value, epoch) | ||||||
|  | 
 | ||||||
|  | 	assert.True(t, checkSignature(sha256sig, seed, key, value, epoch)) | ||||||
|  | 	// This should be switched to False after fully deprecating SHA1
 | ||||||
|  | 	assert.True(t, checkSignature(sha1sig, seed, key, value, epoch)) | ||||||
|  | 
 | ||||||
|  | 	assert.False(t, checkSignature(sha256sig, seed, key, "tampered", epoch)) | ||||||
|  | 	assert.False(t, checkSignature(sha1sig, seed, key, "tampered", epoch)) | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue