Derive every key from the signing key in one place (closes #315)
check / check (push) Canceled after 0s
check / check (push) Canceled after 0s
seal.DeriveKeys derives the session hash and block keys, the encrypted URL key and the CSRF key from the signing key, with their salts declared beside it, and returns them as one seal.Keys. internal/providers calls it once at startup and provides the value to the fx graph. The session manager, the encrypted URL generator and the CSRF protection each take their own key. session.NewManager, encurl.NewGenerator, newCSRFProtect and handlers.New return no error, as nothing in them can fail now. Each key is derived as before, with seal.DeriveKey and the same salt. The signing key itself stays the HMAC key of signed URLs and the login password. README.md says under signing_key what it protects. Model: opus-5-5
This commit was merged in pull request #332.
This commit is contained in:
@@ -16,9 +16,6 @@ const (
|
||||
DefaultQuality = 85
|
||||
DefaultFormat = imagerequest.FormatJXL
|
||||
DefaultFitMode = imagerequest.FitCover
|
||||
|
||||
// HKDF salt for URL encryption key derivation
|
||||
urlKeySalt = "pixa-urlenc-v1"
|
||||
)
|
||||
|
||||
// Errors returned by encurl operations.
|
||||
@@ -48,15 +45,10 @@ type Generator struct {
|
||||
key [seal.KeySize]byte
|
||||
}
|
||||
|
||||
// NewGenerator creates an encrypted URL generator with a key derived
|
||||
// from the signing key.
|
||||
func NewGenerator(signingKey string) (*Generator, error) {
|
||||
key, err := seal.DeriveKey([]byte(signingKey), urlKeySalt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Generator{key: key}, nil
|
||||
// NewGenerator creates an encrypted URL generator that encrypts its tokens
|
||||
// with key.
|
||||
func NewGenerator(key [seal.KeySize]byte) *Generator {
|
||||
return &Generator{key: key}
|
||||
}
|
||||
|
||||
// Generate creates an encrypted URL token from the request's source and
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"sneak.berlin/go/pixa/internal/encurl"
|
||||
"sneak.berlin/go/pixa/internal/imagerequest"
|
||||
"sneak.berlin/go/pixa/internal/seal"
|
||||
)
|
||||
|
||||
// Shared test fixture strings.
|
||||
@@ -19,11 +20,13 @@ const (
|
||||
func TestGenerator_GenerateAndParse(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
gen, err := encurl.NewGenerator("test-signing-key-12345")
|
||||
keys, err := seal.DeriveKeys("test-signing-key-12345")
|
||||
if err != nil {
|
||||
t.Fatalf("NewGenerator() error = %v", err)
|
||||
t.Fatalf("seal.DeriveKeys() error = %v", err)
|
||||
}
|
||||
|
||||
gen := encurl.NewGenerator(keys.EncryptedURLKey)
|
||||
|
||||
req := &imagerequest.Request{
|
||||
Source: imagerequest.Source{
|
||||
Host: testSourceHost,
|
||||
@@ -99,7 +102,8 @@ func TestGenerator_GenerateAndParse(t *testing.T) {
|
||||
func TestGenerator_Parse_Expired(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
gen, _ := encurl.NewGenerator("test-signing-key-12345")
|
||||
keys, _ := seal.DeriveKeys("test-signing-key-12345")
|
||||
gen := encurl.NewGenerator(keys.EncryptedURLKey)
|
||||
|
||||
req := &imagerequest.Request{
|
||||
Source: imagerequest.Source{
|
||||
@@ -126,7 +130,8 @@ func TestGenerator_Parse_Expired(t *testing.T) {
|
||||
func TestGenerator_Parse_InvalidToken(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
gen, _ := encurl.NewGenerator("test-signing-key-12345")
|
||||
keys, _ := seal.DeriveKeys("test-signing-key-12345")
|
||||
gen := encurl.NewGenerator(keys.EncryptedURLKey)
|
||||
|
||||
_, _, err := gen.Parse("not-a-valid-token")
|
||||
if err == nil {
|
||||
@@ -137,7 +142,8 @@ func TestGenerator_Parse_InvalidToken(t *testing.T) {
|
||||
func TestGenerator_Parse_TamperedToken(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
gen, _ := encurl.NewGenerator("test-signing-key-12345")
|
||||
keys, _ := seal.DeriveKeys("test-signing-key-12345")
|
||||
gen := encurl.NewGenerator(keys.EncryptedURLKey)
|
||||
|
||||
req := &imagerequest.Request{
|
||||
Source: imagerequest.Source{
|
||||
@@ -163,8 +169,10 @@ func TestGenerator_Parse_TamperedToken(t *testing.T) {
|
||||
func TestGenerator_Parse_WrongKey(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
gen1, _ := encurl.NewGenerator("signing-key-1")
|
||||
gen2, _ := encurl.NewGenerator("signing-key-2")
|
||||
keys1, _ := seal.DeriveKeys("signing-key-1")
|
||||
keys2, _ := seal.DeriveKeys("signing-key-2")
|
||||
gen1 := encurl.NewGenerator(keys1.EncryptedURLKey)
|
||||
gen2 := encurl.NewGenerator(keys2.EncryptedURLKey)
|
||||
|
||||
req := &imagerequest.Request{
|
||||
Source: imagerequest.Source{
|
||||
@@ -184,7 +192,8 @@ func TestGenerator_Parse_WrongKey(t *testing.T) {
|
||||
func TestGenerator_Parse_Defaults(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
gen, _ := encurl.NewGenerator("test-signing-key-12345")
|
||||
keys, _ := seal.DeriveKeys("test-signing-key-12345")
|
||||
gen := encurl.NewGenerator(keys.EncryptedURLKey)
|
||||
|
||||
// Request with only required fields - should get defaults
|
||||
token, err := gen.Generate(&imagerequest.Request{
|
||||
@@ -221,7 +230,8 @@ func TestGenerator_Parse_Defaults(t *testing.T) {
|
||||
func TestGenerator_TokenIsURLSafe(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
gen, _ := encurl.NewGenerator("test-signing-key-12345")
|
||||
keys, _ := seal.DeriveKeys("test-signing-key-12345")
|
||||
gen := encurl.NewGenerator(keys.EncryptedURLKey)
|
||||
|
||||
req := &imagerequest.Request{
|
||||
Source: imagerequest.Source{
|
||||
|
||||
Reference in New Issue
Block a user