diff options
Diffstat (limited to 'internal/auth')
-rw-r--r-- | internal/auth/auth.go | 26 | ||||
-rw-r--r-- | internal/auth/auth_test.go | 42 |
2 files changed, 51 insertions, 17 deletions
diff --git a/internal/auth/auth.go b/internal/auth/auth.go index 6cbf0842..d6cbdff1 100644 --- a/internal/auth/auth.go +++ b/internal/auth/auth.go @@ -1,10 +1,12 @@ package auth import ( + "crypto/sha256" "encoding/base64" "encoding/json" "errors" "fmt" + "io" "net" "net/http" "net/url" @@ -20,6 +22,8 @@ import ( "gitlab.com/gitlab-org/gitlab-pages/internal/domain" "gitlab.com/gitlab-org/gitlab-pages/internal/httperrors" "gitlab.com/gitlab-org/gitlab-pages/internal/httptransport" + + "golang.org/x/crypto/hkdf" ) const ( @@ -555,9 +559,29 @@ func logRequest(r *http.Request) *log.Entry { }) } +// generateKeyPair returns key pair for secure cookie: signing and encryption key +func generateKeyPair(storeSecret string) ([]byte, []byte) { + hash := sha256.New + hkdf := hkdf.New(hash, []byte(storeSecret), []byte{}, []byte("PAGES_SIGNING_AND_ENCRYPTION_KEY")) + var keys [][]byte + for i := 0; i < 2; i++ { + key := make([]byte, 32) + if _, err := io.ReadFull(hkdf, key); err != nil { + log.WithError(err).Fatal("Can't generate key pair for secure cookies") + } + keys = append(keys, key) + } + return keys[0], keys[1] +} + +func createCookieStore(storeSecret string) sessions.Store { + return sessions.NewCookieStore(generateKeyPair(storeSecret)) +} + // New when authentication supported this will be used to create authentication handler func New(pagesDomain string, storeSecret string, clientID string, clientSecret string, redirectURI string, gitLabServer string) *Auth { + return &Auth{ pagesDomain: pagesDomain, clientID: clientID, @@ -568,6 +592,6 @@ func New(pagesDomain string, storeSecret string, clientID string, clientSecret s Timeout: 5 * time.Second, Transport: httptransport.Transport, }, - store: sessions.NewCookieStore([]byte(storeSecret)), + store: createCookieStore(storeSecret), } } diff --git a/internal/auth/auth_test.go b/internal/auth/auth_test.go index ed130caf..2fbbb938 100644 --- a/internal/auth/auth_test.go +++ b/internal/auth/auth_test.go @@ -1,4 +1,4 @@ -package auth_test +package auth import ( "fmt" @@ -12,12 +12,11 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-pages/internal/auth" "gitlab.com/gitlab-org/gitlab-pages/internal/domain" ) -func createAuth(t *testing.T) *auth.Auth { - return auth.New("pages.gitlab-example.com", +func createAuth(t *testing.T) *Auth { + return New("pages.gitlab-example.com", "something-very-secret", "id", "secret", @@ -25,6 +24,10 @@ func createAuth(t *testing.T) *auth.Auth { "http://gitlab-example.com") } +func defaultCookieStore() sessions.Store { + return createCookieStore("something-very-secret") +} + func TestTryAuthenticate(t *testing.T) { auth := createAuth(t) @@ -85,8 +88,8 @@ func TestTryAuthenticateWithCodeAndState(t *testing.T) { apiServer.Start() defer apiServer.Close() - store := sessions.NewCookieStore([]byte("something-very-secret")) - auth := auth.New("pages.gitlab-example.com", + store := defaultCookieStore() + auth := New("pages.gitlab-example.com", "something-very-secret", "id", "secret", @@ -124,8 +127,8 @@ func TestCheckAuthenticationWhenAccess(t *testing.T) { apiServer.Start() defer apiServer.Close() - store := sessions.NewCookieStore([]byte("something-very-secret")) - auth := auth.New("pages.gitlab-example.com", + store := defaultCookieStore() + auth := New("pages.gitlab-example.com", "something-very-secret", "id", "secret", @@ -161,8 +164,8 @@ func TestCheckAuthenticationWhenNoAccess(t *testing.T) { apiServer.Start() defer apiServer.Close() - store := sessions.NewCookieStore([]byte("something-very-secret")) - auth := auth.New("pages.gitlab-example.com", + store := defaultCookieStore() + auth := New("pages.gitlab-example.com", "something-very-secret", "id", "secret", @@ -199,8 +202,8 @@ func TestCheckAuthenticationWhenInvalidToken(t *testing.T) { apiServer.Start() defer apiServer.Close() - store := sessions.NewCookieStore([]byte("something-very-secret")) - auth := auth.New("pages.gitlab-example.com", + store := defaultCookieStore() + auth := New("pages.gitlab-example.com", "something-very-secret", "id", "secret", @@ -236,8 +239,8 @@ func TestCheckAuthenticationWithoutProject(t *testing.T) { apiServer.Start() defer apiServer.Close() - store := sessions.NewCookieStore([]byte("something-very-secret")) - auth := auth.New("pages.gitlab-example.com", + store := defaultCookieStore() + auth := New("pages.gitlab-example.com", "something-very-secret", "id", "secret", @@ -274,8 +277,8 @@ func TestCheckAuthenticationWithoutProjectWhenInvalidToken(t *testing.T) { apiServer.Start() defer apiServer.Close() - store := sessions.NewCookieStore([]byte("something-very-secret")) - auth := auth.New("pages.gitlab-example.com", + store := defaultCookieStore() + auth := New("pages.gitlab-example.com", "something-very-secret", "id", "secret", @@ -294,3 +297,10 @@ func TestCheckAuthenticationWithoutProjectWhenInvalidToken(t *testing.T) { assert.Equal(t, true, auth.CheckAuthenticationWithoutProject(result, r)) assert.Equal(t, 302, result.Code) } + +func TestGenerateKeyPair(t *testing.T) { + signingSecret, encryptionSecret := generateKeyPair("something-very-secret") + assert.NotEqual(t, fmt.Sprint(signingSecret), fmt.Sprint(encryptionSecret)) + assert.Equal(t, len(signingSecret), 32) + assert.Equal(t, len(encryptionSecret), 32) +} |