mirror of
https://github.com/hashicorp/vault.git
synced 2026-05-04 17:24:55 -04:00
* add dev flag to override pgp key for plugin signature verification -dev-plugin-pgp-key is the path to a PGP public key file to use for plugin signature verification in dev mode. This prevents developers from having to manually hard code their own pgp key into vault source code and rebuild vault to develop and test enterprise plugins. * fix sync once error handling * add tests * remove test * tests: set random listener addr * improve error message * dedupe getVerifyFunc annd verifyPGPSignatureDetached * accept raw key as well as path * keep hc key and add custom key to keyring Co-authored-by: John-Michael Faircloth <fairclothjm@users.noreply.github.com>
221 lines
7.5 KiB
Go
221 lines
7.5 KiB
Go
// Copyright IBM Corp. 2016, 2025
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
//go:build !race && !hsm
|
|
|
|
package command
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// testPGPPublicKey is a sample PGP public key for testing purposes
|
|
const testPGPPublicKey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
|
|
|
|
mQINBGB9+xkBEACabYZOWKmgZsHTdRDiyPJxhbuUiKX65GUWkyRMJKi/1dviVxOX
|
|
PG6hBPtF48IFnVgxKpIb7G6NjBousAV+CuLlv5yqFKpOZEGC6sBV+Gx8Vu1CICpl
|
|
Zm+HpQPcIzwBpN+Ar4l/exCG/f/MZq/oxGgH+TyRF3XcYDjG8dbJCpHO5nQ5Cy9h
|
|
QIp3/Bh09kET6lk+4QlofNgHKVT2epV8iK1cXlbQe2tZtfCUtxk+pxvU0UHXp+AB
|
|
0xc3/gIhjZp/dePmCOyQyGPJbp5bpO4UeAJ6frqhexmNlaw9Z897ltZmRLGq1p4a
|
|
RnWL8FPkBz9SCSKXS8uNyV5oMNVn4G1obCkc106iWuKBTibffYQzq5TG8FYVJKrh
|
|
RwWB6piacEB8hl20IIWSxIM3J9tT7CPSnk5RYYCTRHgA5OOrqZhC7JefudrP8n+M
|
|
pxkDgNORDu7GCfAuisrf7dXYjLsxG4tu22DBJJC0c/IpRpXDnOuJN1Q5e/3VUKKW
|
|
mypNumuQpP5lc1ZFG64TRzb1HR6oIdHfbrVQfdiQXpvdcFx+Fl57WuUraXRV6qfb
|
|
4ZmKHX1JEwM/7tu21QE4F1dz0jroLSricZxfaCTHHWNfvGJoZ30/MZUrpSC0IfB3
|
|
iQutxbZrwIlTBt+fGLtm3vDtwMFNWM+Rb1lrOxEQd2eijdxhvBOHtlIcswARAQAB
|
|
tERIYXNoaUNvcnAgU2VjdXJpdHkgKGhhc2hpY29ycC5jb20vc2VjdXJpdHkpIDxz
|
|
ZWN1cml0eUBoYXNoaWNvcnAuY29tPokCVAQTAQoAPhYhBMh0AR8KtAURDQIQVTQ2
|
|
XZRy10aPBQJgffsZAhsDBQkJZgGABQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJ
|
|
EDQ2XZRy10aPtpcP/0PhJKiHtC1zREpRTrjGizoyk4Sl2SXpBZYhkdrG++abo6zs
|
|
buaAG7kgWWChVXBo5E20L7dbstFK7OjVs7vAg/OLgO9dPD8n2M19rpqSbbvKYWvp
|
|
0NSgvFTT7lbyDhtPj0/bzpkZEhmvQaDWGBsbDdb2dBHGitCXhGMpdP0BuuPWEix+
|
|
QnUMaPwU51q9GM2guL45Tgks9EKNnpDR6ZdCeWcqo1IDmklloidxT8aKL21UOb8t
|
|
cD+Bg8iPaAr73bW7Jh8TdcV6s6DBFub+xPJEB/0bVPmq3ZHs5B4NItroZ3r+h3ke
|
|
VDoSOSIZLl6JtVooOJ2la9ZuMqxchO3mrXLlXxVCo6cGcSuOmOdQSz4OhQE5zBxx
|
|
LuzA5ASIjASSeNZaRnffLIHmht17BPslgNPtm6ufyOk02P5XXwa69UCjA3RYrA2P
|
|
QNNC+OWZ8qQLnzGldqE4MnRNAxRxV6cFNzv14ooKf7+k686LdZrP/3fQu2p3k5rY
|
|
0xQUXKh1uwMUMtGR867ZBYaxYvwqDrg9XB7xi3N6aNyNQ+r7zI2lt65lzwG1v9hg
|
|
FG2AHrDlBkQi/t3wiTS3JOo/GCT8BjN0nJh0lGaRFtQv2cXOQGVRW8+V/9IpqEJ1
|
|
qQreftdBFWxvH7VJq2mSOXUJyRsoUrjkUuIivaA9Ocdipk2CkP8bpuGz7ZF4
|
|
=s1CX
|
|
-----END PGP PUBLIC KEY BLOCK-----`
|
|
|
|
// invalidPGPKey is not a valid PGP key format
|
|
const invalidPGPKey = `This is not a valid PGP key`
|
|
|
|
// testConfig is used to disable prometheus to avoid issues with the
|
|
// global prometheus registry in tests
|
|
const testConfig = `
|
|
storage "inmem" {}
|
|
listener "tcp" {
|
|
address = "127.0.0.1:0"
|
|
tls_disable = true
|
|
}
|
|
disable_mlock = true
|
|
telemetry {
|
|
prometheus_retention_time = "0s"
|
|
disable_hostname = true
|
|
}
|
|
`
|
|
|
|
// TestServer_DevPluginPGPKey_ValidKey tests that the server accepts a valid PGP key file
|
|
func TestServer_DevPluginPGPKey_ValidKey(t *testing.T) {
|
|
// Create a valid PGP key file
|
|
keyPath := filepath.Join(t.TempDir(), "test-pgp-key.asc")
|
|
err := os.WriteFile(keyPath, []byte(testPGPPublicKey), 0o644)
|
|
require.NoError(t, err)
|
|
|
|
ui, cmd := testServerCommand(t)
|
|
args := []string{
|
|
"-dev",
|
|
"-dev-plugin-pgp-key=" + keyPath,
|
|
"-dev-listen-address=127.0.0.1:0",
|
|
"-test-server-config",
|
|
}
|
|
|
|
retCode := cmd.Run(args)
|
|
output := ui.ErrorWriter.String() + ui.OutputWriter.String()
|
|
|
|
// The server should start successfully with a valid key
|
|
require.Equal(t, 0, retCode, "expected server to start successfully, output: %s", output)
|
|
}
|
|
|
|
// TestServer_DevPluginPGPKey_InvalidPath tests that the server handles invalid file paths
|
|
func TestServer_DevPluginPGPKey_InvalidPath(t *testing.T) {
|
|
ui, cmd := testServerCommand(t)
|
|
|
|
// Use an invalid path with null bytes (not allowed in file paths)
|
|
invalidPath := "/tmp/test\x00key.asc"
|
|
|
|
configPath := filepath.Join(t.TempDir(), "config.hcl")
|
|
err := os.WriteFile(configPath, []byte(testConfig), 0o644)
|
|
require.NoError(t, err)
|
|
|
|
args := []string{
|
|
"-dev",
|
|
"-config=" + configPath,
|
|
"-dev-plugin-pgp-key=" + invalidPath,
|
|
"-dev-listen-address=127.0.0.1:0",
|
|
"-test-server-config",
|
|
}
|
|
|
|
retCode := cmd.Run(args)
|
|
output := ui.ErrorWriter.String() + ui.OutputWriter.String()
|
|
|
|
// The server should fail to start with an invalid path
|
|
require.NotEqual(t, 0, retCode, "expected server to fail with invalid path")
|
|
require.Contains(t, output, "dev plugin PGP key", "expected error message about PGP key path, output: %s", output)
|
|
}
|
|
|
|
// TestServer_DevPluginPGPKey_NonExistentFile tests that the server handles non-existent key files
|
|
func TestServer_DevPluginPGPKey_NonExistentFile(t *testing.T) {
|
|
tmpDir := t.TempDir()
|
|
// Use a path that doesn't exist
|
|
keyPath := filepath.Join(tmpDir, "non-existent-key.asc")
|
|
|
|
ui, cmd := testServerCommand(t)
|
|
|
|
configPath := filepath.Join(tmpDir, "config.hcl")
|
|
err := os.WriteFile(configPath, []byte(testConfig), 0o644)
|
|
require.NoError(t, err)
|
|
|
|
args := []string{
|
|
"-dev",
|
|
"-config=" + configPath,
|
|
"-dev-plugin-pgp-key=" + keyPath,
|
|
"-dev-listen-address=127.0.0.1:0",
|
|
"-test-server-config",
|
|
}
|
|
|
|
retCode := cmd.Run(args)
|
|
output := ui.ErrorWriter.String() + ui.OutputWriter.String()
|
|
|
|
// The server should fail to start with a non-existent key file
|
|
require.NotEqual(t, 0, retCode, "expected server to fail with non-existent key file")
|
|
require.Contains(t, output, "dev plugin PGP key", "expected error message about PGP key path, output: %s", output)
|
|
}
|
|
|
|
// TestServer_DevPluginPGPKey_EmptyFlag tests default behavior when flag is not set
|
|
func TestServer_DevPluginPGPKey_EmptyFlag(t *testing.T) {
|
|
ui, cmd := testServerCommand(t)
|
|
|
|
configPath := filepath.Join(t.TempDir(), "config.hcl")
|
|
err := os.WriteFile(configPath, []byte(testConfig), 0o644)
|
|
require.NoError(t, err)
|
|
|
|
args := []string{
|
|
"-dev",
|
|
"-config=" + configPath,
|
|
"-dev-listen-address=127.0.0.1:0",
|
|
"-test-server-config",
|
|
}
|
|
|
|
retCode := cmd.Run(args)
|
|
output := ui.ErrorWriter.String() + ui.OutputWriter.String()
|
|
|
|
// The server should start successfully without the flag (uses default HashiCorp key)
|
|
require.Equal(t, 0, retCode, "expected server to start successfully without flag, output: %s", output)
|
|
}
|
|
|
|
// TestServer_DevPluginPGPKey_InvalidKeyContent tests handling of invalid PGP key content
|
|
func TestServer_DevPluginPGPKey_InvalidKeyContent(t *testing.T) {
|
|
tmpDir := t.TempDir()
|
|
// Create a file with invalid PGP key content
|
|
keyPath := filepath.Join(tmpDir, "invalid-key.asc")
|
|
err := os.WriteFile(keyPath, []byte(invalidPGPKey), 0o644)
|
|
require.NoError(t, err)
|
|
|
|
ui, cmd := testServerCommand(t)
|
|
|
|
configPath := filepath.Join(tmpDir, "config.hcl")
|
|
err = os.WriteFile(configPath, []byte(testConfig), 0o644)
|
|
require.NoError(t, err)
|
|
|
|
args := []string{
|
|
"-dev",
|
|
"-config=" + configPath,
|
|
"-dev-plugin-pgp-key=" + keyPath,
|
|
"-dev-listen-address=127.0.0.1:0",
|
|
"-test-server-config",
|
|
}
|
|
|
|
retCode := cmd.Run(args)
|
|
output := ui.ErrorWriter.String() + ui.OutputWriter.String()
|
|
|
|
// The server should start (validation happens when actually using the key)
|
|
// but we verify the path was set correctly
|
|
require.Equal(t, 0, retCode, "expected server to start (key validation happens at use time), output: %s", output)
|
|
}
|
|
|
|
// TestServer_DevPluginPGPKey_EmptyFile tests handling of an empty key file
|
|
func TestServer_DevPluginPGPKey_EmptyFile(t *testing.T) {
|
|
tmpDir := t.TempDir()
|
|
// Create an empty file
|
|
keyPath := filepath.Join(tmpDir, "empty-key.asc")
|
|
err := os.WriteFile(keyPath, []byte(""), 0o644)
|
|
require.NoError(t, err)
|
|
|
|
ui, cmd := testServerCommand(t)
|
|
|
|
configPath := filepath.Join(tmpDir, "config.hcl")
|
|
err = os.WriteFile(configPath, []byte(testConfig), 0o644)
|
|
require.NoError(t, err)
|
|
|
|
args := []string{
|
|
"-dev",
|
|
"-config=" + configPath,
|
|
"-dev-plugin-pgp-key=" + keyPath,
|
|
"-dev-listen-address=127.0.0.1:0",
|
|
"-test-server-config",
|
|
}
|
|
|
|
retCode := cmd.Run(args)
|
|
output := ui.ErrorWriter.String() + ui.OutputWriter.String()
|
|
|
|
// The server should start (validation happens when actually using the key)
|
|
require.Equal(t, 0, retCode, "expected server to start (key validation happens at use time), output: %s", output)
|
|
}
|