Merge pull request #2236 from hashicorp/pgp-keys-check

rekey: added check to ensure that length of PGP keys and the shares are matching
This commit is contained in:
Vishal Nayak 2017-01-12 11:19:08 -05:00 committed by GitHub
commit bbae05307b
6 changed files with 78 additions and 3 deletions

View File

@ -329,13 +329,16 @@ Init Options:
-pgp-keys If provided, must be a comma-separated list of -pgp-keys If provided, must be a comma-separated list of
files on disk containing binary- or base64-format files on disk containing binary- or base64-format
public PGP keys, or Keybase usernames specified as public PGP keys, or Keybase usernames specified as
"keybase:<username>". The number of given entries "keybase:<username>". The output unseal keys will
must match 'key-shares'. The output unseal keys will
be encrypted and base64-encoded, in order, with the be encrypted and base64-encoded, in order, with the
given public keys. If you want to use them with the given public keys. If you want to use them with the
'vault unseal' command, you will need to base64- 'vault unseal' command, you will need to base64-
decode and decrypt; this will be the plaintext decode and decrypt; this will be the plaintext
unseal key. unseal key. When 'stored-shares' are not used, the
number of entries in this field must match 'key-shares'.
When 'stored-shares' are used, the number of entries
should match the difference between 'key-shares'
and 'stored-shares'.
-root-token-pgp-key If provided, a file on disk with a binary- or -root-token-pgp-key If provided, a file on disk with a binary- or
base64-format public PGP key, or a Keybase username base64-format public PGP key, or a Keybase username

View File

@ -81,6 +81,18 @@ func handleSysInitPut(core *vault.Core, w http.ResponseWriter, r *http.Request)
} }
} }
if len(barrierConfig.PGPKeys) > 0 && len(barrierConfig.PGPKeys) != barrierConfig.SecretShares-barrierConfig.StoredShares {
respondError(w, http.StatusBadRequest, fmt.Errorf("incorrect number of PGP keys"))
return
}
if core.SealAccess().RecoveryKeySupported() {
if len(recoveryConfig.PGPKeys) > 0 && len(recoveryConfig.PGPKeys) != recoveryConfig.SecretShares-recoveryConfig.StoredShares {
respondError(w, http.StatusBadRequest, fmt.Errorf("incorrect number of PGP keys for recovery"))
return
}
}
initParams := &vault.InitParams{ initParams := &vault.InitParams{
BarrierConfig: barrierConfig, BarrierConfig: barrierConfig,
RecoveryConfig: recoveryConfig, RecoveryConfig: recoveryConfig,

View File

@ -53,6 +53,39 @@ func TestSysInit_get(t *testing.T) {
} }
} }
// Test to check if the API errors out when wrong number of PGP keys are
// supplied
func TestSysInit_pgpKeysEntries(t *testing.T) {
core := vault.TestCore(t)
ln, addr := TestServer(t, core)
defer ln.Close()
resp := testHttpPut(t, "", addr+"/v1/sys/init", map[string]interface{}{
"secret_shares": 5,
"secret_threhold": 3,
"pgp_keys": []string{"pgpkey1"},
})
testResponseStatus(t, resp, 400)
}
// Test to check if the API errors out when wrong number of PGP keys are
// supplied for recovery config
func TestSysInit_pgpKeysEntriesForRecovery(t *testing.T) {
core := vault.TestCoreNewSeal(t)
ln, addr := TestServer(t, core)
defer ln.Close()
resp := testHttpPut(t, "", addr+"/v1/sys/init", map[string]interface{}{
"secret_shares": 1,
"secret_threshold": 1,
"stored_shares": 1,
"recovery_shares": 5,
"recovery_threshold": 3,
"recovery_pgp_keys": []string{"pgpkey1"},
})
testResponseStatus(t, resp, 400)
}
func TestSysInit_put(t *testing.T) { func TestSysInit_put(t *testing.T) {
core := vault.TestCore(t) core := vault.TestCore(t)
ln, addr := TestServer(t, core) ln, addr := TestServer(t, core)

View File

@ -113,6 +113,11 @@ func handleSysRekeyInitPut(core *vault.Core, recovery bool, w http.ResponseWrite
return return
} }
if len(req.PGPKeys) > 0 && len(req.PGPKeys) != req.SecretShares-req.StoredShares {
respondError(w, http.StatusBadRequest, fmt.Errorf("incorrect number of PGP keys for rekey"))
return
}
// Initialize the rekey // Initialize the rekey
err := core.RekeyInit(&vault.SealConfig{ err := core.RekeyInit(&vault.SealConfig{
SecretShares: req.SecretShares, SecretShares: req.SecretShares,

View File

@ -10,6 +10,22 @@ import (
"github.com/hashicorp/vault/vault" "github.com/hashicorp/vault/vault"
) )
// Test to check if the API errors out when wrong number of PGP keys are
// supplied for rekey
func TestSysRekeyInit_pgpKeysEntriesForRekey(t *testing.T) {
core, _, token := vault.TestCoreUnsealed(t)
ln, addr := TestServer(t, core)
defer ln.Close()
TestServerAuth(t, addr, token)
resp := testHttpPut(t, token, addr+"/v1/sys/rekey/init", map[string]interface{}{
"secret_shares": 5,
"secret_threshold": 3,
"pgp_keys": []string{"pgpkey1"},
})
testResponseStatus(t, resp, 400)
}
func TestSysRekeyInit_Status(t *testing.T) { func TestSysRekeyInit_Status(t *testing.T) {
core, _, token := vault.TestCoreUnsealed(t) core, _, token := vault.TestCoreUnsealed(t)
ln, addr := TestServer(t, core) ln, addr := TestServer(t, core)

View File

@ -70,6 +70,12 @@ func TestCore(t *testing.T) *Core {
return TestCoreWithSeal(t, nil) return TestCoreWithSeal(t, nil)
} }
// TestCoreNewSeal returns an in-memory, ininitialized core with the new seal
// configuration.
func TestCoreNewSeal(t *testing.T) *Core {
return TestCoreWithSeal(t, &TestSeal{})
}
// TestCoreWithSeal returns a pure in-memory, uninitialized core with the // TestCoreWithSeal returns a pure in-memory, uninitialized core with the
// specified seal for testing. // specified seal for testing.
func TestCoreWithSeal(t *testing.T, testSeal Seal) *Core { func TestCoreWithSeal(t *testing.T, testSeal Seal) *Core {