Re-add lost stored-shares parameter to operator rekey command. (#3974)

Also change the rekey API to not require explicitly setting values to 1.

Fixes #3969
This commit is contained in:
Jeff Mitchell 2018-02-14 16:10:45 -05:00 committed by GitHub
parent d838195241
commit a787f97a9c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 43 additions and 35 deletions

View File

@ -196,15 +196,6 @@ func (c *OperatorInitCommand) Flags() *FlagSets {
"is only used in HSM mode.",
})
f.IntVar(&IntVar{
Name: "stored-shares",
Target: &c.flagStoredShares,
Default: 0, // No default, because we need to check if was supplied
Completion: complete.PredictAnything,
Usage: "Number of unseal keys to store on an HSM. This must be equal to " +
"-key-shares. This is only used in HSM mode.",
})
// Deprecations
// TODO: remove in 0.9.0
f.BoolVar(&BoolVar{
@ -222,6 +213,15 @@ func (c *OperatorInitCommand) Flags() *FlagSets {
Usage: "",
})
// Kept to keep scripts passing the flag working, but not used
f.IntVar(&IntVar{
Name: "stored-shares",
Target: &c.flagStoredShares,
Default: 0,
Hidden: true,
Usage: "",
})
return set
}
@ -456,7 +456,7 @@ func (c *OperatorInitCommand) init(client *api.Client, req *api.InitRequest) int
c.UI.Output("")
c.UI.Output(fmt.Sprintf("Initial Root Token: %s", resp.RootToken))
if req.StoredShares < 1 {
if len(resp.Keys) > 0 {
c.UI.Output("")
c.UI.Output(wrapAtLength(fmt.Sprintf(
"Vault initialized with %d key shares and a key threshold of %d. Please "+

View File

@ -37,9 +37,10 @@ type OperatorRekeyCommand struct {
// Deprecations
// TODO: remove in 0.9.0
flagDelete bool
flagRecoveryKey bool
flagRetrieve bool
flagDelete bool
flagRecoveryKey bool
flagRetrieve bool
flagStoredShares int
testStdin io.Reader // for tests
}
@ -231,6 +232,15 @@ func (c *OperatorRekeyCommand) Flags() *FlagSets {
Usage: "",
})
// Kept to keep scripts passing the flag working, but not used
f.IntVar(&IntVar{
Name: "stored-shares",
Target: &c.flagStoredShares,
Default: 0,
Hidden: true,
Usage: "",
})
return set
}
@ -323,6 +333,7 @@ func (c *OperatorRekeyCommand) init(client *api.Client) int {
status, err := fn(&api.RekeyInitRequest{
SecretShares: c.flagKeyShares,
SecretThreshold: c.flagKeyThreshold,
StoredShares: c.flagStoredShares,
PGPKeys: c.flagPGPKeys,
Backup: c.flagBackup,
})

View File

@ -69,36 +69,28 @@ func handleSysInitPut(core *vault.Core, w http.ResponseWriter, r *http.Request)
// need to be a way to actually allow fetching of the generated keys by
// operators.
if core.SealAccess().StoredKeysSupported() {
if barrierConfig.SecretShares != 1 {
respondError(w, http.StatusBadRequest, fmt.Errorf("secret shares must be 1"))
return
}
if barrierConfig.SecretThreshold != barrierConfig.SecretShares {
respondError(w, http.StatusBadRequest, fmt.Errorf("secret threshold must be same as secret shares"))
return
}
if barrierConfig.StoredShares != barrierConfig.SecretShares {
respondError(w, http.StatusBadRequest, fmt.Errorf("stored shares must be same as secret shares"))
return
}
if barrierConfig.PGPKeys != nil && len(barrierConfig.PGPKeys) > 0 {
if len(barrierConfig.PGPKeys) > 0 {
respondError(w, http.StatusBadRequest, fmt.Errorf("PGP keys not supported when storing shares"))
return
}
barrierConfig.SecretShares = 1
barrierConfig.SecretThreshold = 1
barrierConfig.StoredShares = 1
core.Logger().Warn("init: stored keys supported, forcing shares/threshold to 1")
} else {
if barrierConfig.StoredShares > 0 {
respondError(w, http.StatusBadRequest, fmt.Errorf("stored keys are not supported"))
respondError(w, http.StatusBadRequest, fmt.Errorf("stored keys are not supported by the current seal type"))
return
}
}
if len(barrierConfig.PGPKeys) > 0 && len(barrierConfig.PGPKeys) != barrierConfig.SecretShares-barrierConfig.StoredShares {
if len(barrierConfig.PGPKeys) > 0 && len(barrierConfig.PGPKeys) != barrierConfig.SecretShares {
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 {
if len(recoveryConfig.PGPKeys) > 0 && len(recoveryConfig.PGPKeys) != recoveryConfig.SecretShares {
respondError(w, http.StatusBadRequest, fmt.Errorf("incorrect number of PGP keys for recovery"))
return
}

View File

@ -117,16 +117,21 @@ func handleSysRekeyInitPut(ctx context.Context, core *vault.Core, recovery bool,
return
}
// If the seal supports recovery keys and stored keys, then we allow rekeying the barrier key
// iff the secret shares, secret threshold, and stored shares are set to 1.
if !recovery && core.SealAccess().RecoveryKeySupported() && core.SealAccess().StoredKeysSupported() {
if req.SecretShares != 1 || req.SecretThreshold != 1 || req.StoredShares != 1 {
respondError(w, http.StatusBadRequest, fmt.Errorf("secret shares, secret threshold, and stored shares must be set to 1"))
// If the seal supports stored keys, and we are rekeying the barrier key,
// force the shares to 1
if !recovery && core.SealAccess().StoredKeysSupported() {
req.SecretShares = 1
req.SecretThreshold = 1
req.StoredShares = 1
core.Logger().Warn("rekey: stored keys supported, forcing shares/threshold to 1")
} else {
if req.StoredShares != 0 {
respondError(w, http.StatusBadRequest, fmt.Errorf("stored keys are not supported by the current seal type"))
return
}
}
if len(req.PGPKeys) > 0 && len(req.PGPKeys) != req.SecretShares-req.StoredShares {
if len(req.PGPKeys) > 0 && len(req.PGPKeys) != req.SecretShares {
respondError(w, http.StatusBadRequest, fmt.Errorf("incorrect number of PGP keys for rekey"))
return
}