vault: adding sys/key-status and sys/rotate

This commit is contained in:
Armon Dadgar 2015-05-27 17:53:42 -07:00
parent 26cff2f42f
commit d0b93a6164
2 changed files with 111 additions and 0 deletions

View File

@ -25,6 +25,7 @@ func NewSystemBackend(core *Core) logical.Backend {
"audit/*",
"seal", // Must be set for Core.Seal() logic
"raw/*",
"rotate",
},
},
@ -281,6 +282,28 @@ func NewSystemBackend(core *Core) logical.Backend {
logical.DeleteOperation: b.handleRawDelete,
},
},
&framework.Path{
Pattern: "key-status$",
Callbacks: map[logical.Operation]framework.OperationFunc{
logical.ReadOperation: b.handleKeyStatus,
},
HelpSynopsis: strings.TrimSpace(sysHelp["key-status"][0]),
HelpDescription: strings.TrimSpace(sysHelp["key-status"][1]),
},
&framework.Path{
Pattern: "rotate$",
Callbacks: map[logical.Operation]framework.OperationFunc{
logical.WriteOperation: b.handleRotate,
},
HelpSynopsis: strings.TrimSpace(sysHelp["rotate"][0]),
HelpDescription: strings.TrimSpace(sysHelp["rotate"][1]),
},
},
}
return b.Backend
@ -669,6 +692,33 @@ func (b *SystemBackend) handleRawDelete(
return nil, nil
}
// handleKeyStatus returns status information about the backend key
func (b *SystemBackend) handleKeyStatus(
req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
// Get the key info
info, err := b.Core.barrier.ActiveKeyInfo()
if err != nil {
return nil, err
}
resp := &logical.Response{
Data: map[string]interface{}{
"term": info.Term,
"install_time": info.InstallTime,
},
}
return resp, nil
}
// handleRotate is used to trigger a key rotation
func (b *SystemBackend) handleRotate(
req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
if err := b.Core.barrier.Rotate(); err != nil {
return logical.ErrorResponse(err.Error()), logical.ErrInvalidRequest
}
return nil, nil
}
const sysHelpRoot = `
The system backend is built-in to Vault and cannot be remounted or
unmounted. It contains the paths that are used to configure Vault itself
@ -866,4 +916,20 @@ a user friendly description of the audit backend, and it's configuration options
Enable a new audit backend or disable an existing backend.
`,
},
"key-status": {
"Provides information about the backend encryption key.",
`
Provides the current backend encryption key term and installation time.
`,
},
"rotate": {
"Rotates the backend encryption key used to persist data.",
`
Rotate generates a new encryption key which is used to encrypt all
data going to the storage backend. The old encryption keys are kept so
that data encrypted using those keys can still be decrypted.
`,
},
}

View File

@ -20,6 +20,7 @@ func TestSystemBackend_RootPaths(t *testing.T) {
"audit/*",
"seal",
"raw/*",
"rotate",
}
b := testSystemBackend(t)
@ -669,6 +670,50 @@ func TestSystemBackend_rawDelete(t *testing.T) {
}
}
func TestSystemBackend_keyStatus(t *testing.T) {
b := testSystemBackend(t)
req := logical.TestRequest(t, logical.ReadOperation, "key-status")
resp, err := b.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
}
exp := map[string]interface{}{
"term": 1,
}
delete(resp.Data, "install_time")
if !reflect.DeepEqual(resp.Data, exp) {
t.Fatalf("got: %#v expect: %#v", resp.Data, exp)
}
}
func TestSystemBackend_rotate(t *testing.T) {
b := testSystemBackend(t)
req := logical.TestRequest(t, logical.WriteOperation, "rotate")
resp, err := b.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
}
if resp != nil {
t.Fatalf("bad: %v", resp)
}
req = logical.TestRequest(t, logical.ReadOperation, "key-status")
resp, err = b.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
}
exp := map[string]interface{}{
"term": 2,
}
delete(resp.Data, "install_time")
if !reflect.DeepEqual(resp.Data, exp) {
t.Fatalf("got: %#v expect: %#v", resp.Data, exp)
}
}
func testSystemBackend(t *testing.T) logical.Backend {
c, _, _ := TestCoreUnsealed(t)
return NewSystemBackend(c)