3 files changed, 34 insertions(+), 22 deletions(-)

M cookies/cookies.go
M crypto/crypto.go
M crypto/middleware.go
M cookies/cookies.go +4 -21
@@ 23,23 23,6 @@ var (
 	ErrInvalidValue = errors.New("invalid cookie value")
 )
 
-// KeyWallet is a simple struct to pass on various keys. The
-// reasoning is for cases where you have to change a secret
-// key without affecting already encrypted/signed data that's
-// in the wild.
-//
-// # The first key in `Keys` should be the current main key
-//
-// If `Reset` is true then if any key, other than the current
-// main key was used for the cookie signing/encryption it will
-// resign/encrypt the value with the current main key. Mainly
-// useful for edge cases where you need to phase out an old
-// key for whatever reason
-type KeyWallet struct {
-	Keys  [][]byte
-	Reset bool
-}
-
 // Set will set a cookie with no additional processing.
 func Set(c echo.Context, cookie *http.Cookie) {
 	c.SetCookie(cookie)

          
@@ 92,7 75,7 @@ func GetEncode(c echo.Context, name stri
 }
 
 // SetSigned will set a cookie and sign the value
-func SetSigned(c echo.Context, cookie *http.Cookie, kw *KeyWallet) error {
+func SetSigned(c echo.Context, cookie *http.Cookie, kw *crypto.KeyWallet) error {
 	mac := hmac.New(sha256.New, kw.Keys[0])
 	mac.Write([]byte(cookie.Name))
 	mac.Write([]byte(cookie.Value))

          
@@ 109,7 92,7 @@ func SetSigned(c echo.Context, cookie *h
 }
 
 // GetSigned will get a cookie and verify it's signature
-func GetSigned(c echo.Context, name string, kw *KeyWallet) (*http.Cookie, error) {
+func GetSigned(c echo.Context, name string, kw *crypto.KeyWallet) (*http.Cookie, error) {
 	cookie, err := Get(c, name)
 	if err != nil {
 		return nil, err

          
@@ 154,7 137,7 @@ func GetSigned(c echo.Context, name stri
 }
 
 // SetEncrypted will set a cookie that is encrypted
-func SetEncrypted(c echo.Context, cookie *http.Cookie, kw *KeyWallet) error {
+func SetEncrypted(c echo.Context, cookie *http.Cookie, kw *crypto.KeyWallet) error {
 	// Prepare the plaintext input for encryption. Because we want to
 	// authenticate the cookie name as well as the value, we make this plaintext
 	// in the format "{cookie name}:{cookie value}". We use the : character as a

          
@@ 181,7 164,7 @@ func SetEncrypted(c echo.Context, cookie
 }
 
 // GetEncrypted will get an encrypted cookie and decrypt it
-func GetEncrypted(c echo.Context, name string, kw *KeyWallet) (*http.Cookie, error) {
+func GetEncrypted(c echo.Context, name string, kw *crypto.KeyWallet) (*http.Cookie, error) {
 	cookie, err := Get(c, name)
 	if err != nil {
 		return nil, err

          
M crypto/crypto.go +17 -0
@@ 14,6 14,23 @@ import (
 // ErrInvalidValue ...
 var ErrInvalidValue = errors.New("invalid encrypted value")
 
+// KeyWallet is a simple struct to pass on various keys. The
+// reasoning is for cases where you have to change a secret
+// key without affecting already encrypted/signed data that's
+// in the wild.
+//
+// # The first key in `Keys` should be the current main key
+//
+// If `Reset` is true then if any key, other than the current
+// main key was used for the cookie signing/encryption it will
+// resign/encrypt the value with the current main key. Mainly
+// useful for edge cases where you need to phase out an old
+// key for whatever reason
+type KeyWallet struct {
+	Keys  [][]byte
+	Reset bool
+}
+
 // GenerateKey will generate a random key of `keylen` length to be
 // used for cookie signing and/or encryption. If `alpha` is true then the key
 // will consist of only alphanumeric characters (plus common symbols)

          
M crypto/middleware.go +13 -1
@@ 3,6 3,7 @@ package crypto
 import (
 	"context"
 	"errors"
+	"strings"
 )
 
 var cryptoCtxKey = &contextKey{"crypto"}

          
@@ 16,7 17,7 @@ func Context(ctx context.Context, crypto
 	return context.WithValue(ctx, cryptoCtxKey, crypto)
 }
 
-// ForContext pulls *sql.DB obj for context
+// ForContext pulls crypto value for context
 func ForContext(ctx context.Context) string {
 	crypto, ok := ctx.Value(cryptoCtxKey).(string)
 	if !ok {

          
@@ 24,3 25,14 @@ func ForContext(ctx context.Context) str
 	}
 	return crypto
 }
+
+// KWForContext pulls crypto value for context and stores it into a KeyWallet
+func KWForContext(ctx context.Context) *KeyWallet {
+	contextKeys := ForContext(ctx)
+	keys := strings.Split(contextKeys, " ")
+	kw := &KeyWallet{}
+	for _, key := range keys {
+		kw.Keys = append(kw.Keys, []byte(key))
+	}
+	return kw
+}