mirror of https://github.com/portainer/portainer
fix(encryption): in fips mode, use pbkdf2 for db password [be-11933] (#985)
Co-authored-by: andres-portainer <andres-portainer@users.noreply.github.com>pull/12788/merge
parent
64ed988169
commit
2cf1649c67
|
@ -307,8 +307,19 @@ func initKeyPair(fileService portainer.FileService, signatureService portainer.D
|
|||
return generateAndStoreKeyPair(fileService, signatureService)
|
||||
}
|
||||
|
||||
// dbSecretPath build the path to the file that contains the db encryption
|
||||
// secret. Normally in Docker this is built from the static path inside
|
||||
// /run/portainer for example: /run/portainer/<keyFilenameFlag> but for ease of
|
||||
// use outside Docker it also accepts an absolute path
|
||||
func dbSecretPath(keyFilenameFlag string) string {
|
||||
if path.IsAbs(keyFilenameFlag) {
|
||||
return keyFilenameFlag
|
||||
}
|
||||
return path.Join("/run/portainer", keyFilenameFlag)
|
||||
}
|
||||
|
||||
func loadEncryptionSecretKey(keyfilename string) []byte {
|
||||
content, err := os.ReadFile(path.Join("/run/secrets", keyfilename))
|
||||
content, err := os.ReadFile(keyfilename)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
log.Info().Str("filename", keyfilename).Msg("encryption key file not present")
|
||||
|
@ -320,6 +331,7 @@ func loadEncryptionSecretKey(keyfilename string) []byte {
|
|||
}
|
||||
|
||||
// return a 32 byte hash of the secret (required for AES)
|
||||
// fips compliant version of this is not implemented in -ce
|
||||
hash := sha256.Sum256(content)
|
||||
|
||||
return hash[:]
|
||||
|
@ -348,7 +360,7 @@ func buildServer(flags *portainer.CLIFlags) portainer.Server {
|
|||
fips.InitFIPS(false)
|
||||
|
||||
fileService := initFileService(*flags.Data)
|
||||
encryptionKey := loadEncryptionSecretKey(*flags.SecretKeyName)
|
||||
encryptionKey := loadEncryptionSecretKey(dbSecretPath(*flags.SecretKeyName))
|
||||
if encryptionKey == nil {
|
||||
log.Info().Msg("proceeding without encryption key")
|
||||
}
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const secretFileName = "secret.txt"
|
||||
|
||||
func createPasswordFile(t *testing.T, secretPath, password string) string {
|
||||
err := os.WriteFile(secretPath, []byte(password), 0600)
|
||||
require.NoError(t, err)
|
||||
return secretPath
|
||||
}
|
||||
|
||||
func TestLoadEncryptionSecretKey(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
secretPath := path.Join(tempDir, secretFileName)
|
||||
|
||||
// first pointing to file that does not exist, gives nil hash (no encryption)
|
||||
encryptionKey := loadEncryptionSecretKey(secretPath)
|
||||
require.Nil(t, encryptionKey)
|
||||
|
||||
// point to a directory instead of a file
|
||||
encryptionKey = loadEncryptionSecretKey(tempDir)
|
||||
require.Nil(t, encryptionKey)
|
||||
|
||||
password := "portainer@1234"
|
||||
createPasswordFile(t, secretPath, password)
|
||||
|
||||
encryptionKey = loadEncryptionSecretKey(secretPath)
|
||||
require.NotNil(t, encryptionKey)
|
||||
// should be 32 bytes for aes256 encryption
|
||||
require.Len(t, encryptionKey, 32)
|
||||
}
|
||||
|
||||
func TestDBSecretPath(t *testing.T) {
|
||||
tests := []struct {
|
||||
keyFilenameFlag string
|
||||
expected string
|
||||
}{
|
||||
{keyFilenameFlag: "secret.txt", expected: "/run/portainer/secret.txt"},
|
||||
{keyFilenameFlag: "/tmp/secret.txt", expected: "/tmp/secret.txt"},
|
||||
{keyFilenameFlag: "/run/portainer/secret.txt", expected: "/run/portainer/secret.txt"},
|
||||
{keyFilenameFlag: "./secret.txt", expected: "/run/portainer/secret.txt"},
|
||||
{keyFilenameFlag: "../secret.txt", expected: "/run/secret.txt"},
|
||||
{keyFilenameFlag: "foo/bar/secret.txt", expected: "/run/portainer/foo/bar/secret.txt"},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
assert.Equal(t, test.expected, dbSecretPath(test.keyFilenameFlag))
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue