71 lines
2.6 KiB
Go
71 lines
2.6 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
|
|
"gitea.perlbach24.de/scripte/nexarch/internal/kek"
|
|
"gitea.perlbach24.de/scripte/nexarch/internal/moduletrust"
|
|
)
|
|
|
|
// QA-15 F-10: eigener Schluesselsatz fuer Sitzungstokens (Tabelle
|
|
// session_signing_keys), unabhaengig vom Modul-Signaturschluessel aus
|
|
// API-16 (module_signing_keys) — getrennte Sicherheitsdomaenen, siehe
|
|
// Migration 0010. Envs bewusst analog zu modulekeys.go benannt.
|
|
const (
|
|
envSessionKeyEncryptionKey = "NEXARCH_ACCOUNT_SESSION_KEY_ENCRYPTION_KEY"
|
|
envSessionKeysEphemeral = "NEXARCH_ACCOUNT_SESSION_KEYS_EPHEMERAL"
|
|
envSessionKeyRotationDays = "NEXARCH_ACCOUNT_SESSION_KEY_ROTATION_DAYS"
|
|
envSessionKeyActivationSecs = "NEXARCH_ACCOUNT_SESSION_KEY_ACTIVATION_DELAY_SECONDS"
|
|
envSessionKeyRefreshSecs = "NEXARCH_ACCOUNT_SESSION_KEY_REFRESH_SECONDS"
|
|
|
|
defaultSessionRotationDays = 30
|
|
defaultSessionActivationSecs = 120
|
|
defaultSessionRefreshSecs = 30
|
|
)
|
|
|
|
func newSessionKeyManager(ctx context.Context, pool *pgxpool.Pool, getenv func(string) string, tokenTTL time.Duration) (*moduletrust.KeyManager, error) {
|
|
ephemeral := false
|
|
switch getenv(envSessionKeysEphemeral) {
|
|
case "", "false":
|
|
case "true":
|
|
ephemeral = true
|
|
default:
|
|
return nil, fmt.Errorf("%s: erlaubt sind true oder false", envSessionKeysEphemeral)
|
|
}
|
|
days, err := intEnv(getenv, envSessionKeyRotationDays, defaultSessionRotationDays, 0, 3650)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
act, err := intEnv(getenv, envSessionKeyActivationSecs, defaultSessionActivationSecs, 60, 3600)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
refresh, err := intEnv(getenv, envSessionKeyRefreshSecs, defaultSessionRefreshSecs, 1, 300)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if act < refresh {
|
|
return nil, fmt.Errorf("%s (%ds) darf nicht kuerzer sein als %s (%ds)", envSessionKeyActivationSecs, act, envSessionKeyRefreshSecs, refresh)
|
|
}
|
|
|
|
if ephemeral {
|
|
return moduletrust.NewKeyManager()
|
|
}
|
|
key, err := kek.LoadMasterKeyFromEnv(envSessionKeyEncryptionKey)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("%s: %w (ohne persistente schluessel nur mit %s=true, dann ungueltig nach jedem neustart)", envSessionKeyEncryptionKey, err, envSessionKeysEphemeral)
|
|
}
|
|
return moduletrust.NewPersistentKeyManager(ctx, moduletrust.PersistentConfig{
|
|
Store: moduletrust.NewSessionPGKeyStore(pool),
|
|
Cipher: kekCipher{key: key},
|
|
TokenTTL: tokenTTL,
|
|
ActivationDelay: time.Duration(act) * time.Second,
|
|
RotationInterval: time.Duration(days) * 24 * time.Hour,
|
|
RefreshInterval: time.Duration(refresh) * time.Second,
|
|
})
|
|
}
|