From e9538f1441cca29ec14f4ed463ad44f354b6f4fa Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Fri, 15 Jan 2016 10:55:35 -0500 Subject: [PATCH] RootGeneration->GenerateRoot --- ...oot_generation.go => sys_generate_root.go} | 22 ++-- command/generate-root.go | 28 ++--- command/generate-root_test.go | 12 +- helper/xor/xor_test.go | 23 ---- http/handler.go | 4 +- ...oot_generation.go => sys_generate_root.go} | 42 +++---- ...tion_test.go => sys_generate_root_test.go} | 62 +++++----- vault/core.go | 8 +- .../{root_generation.go => generate_root.go} | 114 +++++++++--------- ...neration_test.go => generate_root_test.go} | 72 +++++------ vault/testing.go | 22 ++++ ...tion.html.md => sys-generate-root.html.md} | 18 +-- website/source/layouts/http.erb | 4 +- 13 files changed, 215 insertions(+), 216 deletions(-) rename api/{sys_root_generation.go => sys_generate_root.go} (60%) rename http/{sys_root_generation.go => sys_generate_root.go} (73%) rename http/{sys_root_generation_test.go => sys_generate_root_test.go} (79%) rename vault/{root_generation.go => generate_root.go} (66%) rename vault/{root_generation_test.go => generate_root_test.go} (69%) rename website/source/docs/http/{sys-root-generation.html.md => sys-generate-root.html.md} (90%) diff --git a/api/sys_root_generation.go b/api/sys_generate_root.go similarity index 60% rename from api/sys_root_generation.go rename to api/sys_generate_root.go index e50b0beccb..bc185c962b 100644 --- a/api/sys_root_generation.go +++ b/api/sys_generate_root.go @@ -1,25 +1,25 @@ package api -func (c *Sys) RootGenerationStatus() (*RootGenerationStatusResponse, error) { - r := c.c.NewRequest("GET", "/v1/sys/root-generation/attempt") +func (c *Sys) GenerateRootStatus() (*GenerateRootStatusResponse, error) { + r := c.c.NewRequest("GET", "/v1/sys/generate-root/attempt") resp, err := c.c.RawRequest(r) if err != nil { return nil, err } defer resp.Body.Close() - var result RootGenerationStatusResponse + var result GenerateRootStatusResponse err = resp.DecodeJSON(&result) return &result, err } -func (c *Sys) RootGenerationInit(otp, pgpKey string) error { +func (c *Sys) GenerateRootInit(otp, pgpKey string) error { body := map[string]interface{}{ "otp": otp, "pgp_key": pgpKey, } - r := c.c.NewRequest("PUT", "/v1/sys/root-generation/attempt") + r := c.c.NewRequest("PUT", "/v1/sys/generate-root/attempt") if err := r.SetJSONBody(body); err != nil { return err } @@ -31,8 +31,8 @@ func (c *Sys) RootGenerationInit(otp, pgpKey string) error { return err } -func (c *Sys) RootGenerationCancel() error { - r := c.c.NewRequest("DELETE", "/v1/sys/root-generation/attempt") +func (c *Sys) GenerateRootCancel() error { + r := c.c.NewRequest("DELETE", "/v1/sys/generate-root/attempt") resp, err := c.c.RawRequest(r) if err == nil { defer resp.Body.Close() @@ -40,13 +40,13 @@ func (c *Sys) RootGenerationCancel() error { return err } -func (c *Sys) RootGenerationUpdate(shard, nonce string) (*RootGenerationStatusResponse, error) { +func (c *Sys) GenerateRootUpdate(shard, nonce string) (*GenerateRootStatusResponse, error) { body := map[string]interface{}{ "key": shard, "nonce": nonce, } - r := c.c.NewRequest("PUT", "/v1/sys/root-generation/update") + r := c.c.NewRequest("PUT", "/v1/sys/generate-root/update") if err := r.SetJSONBody(body); err != nil { return nil, err } @@ -57,12 +57,12 @@ func (c *Sys) RootGenerationUpdate(shard, nonce string) (*RootGenerationStatusRe } defer resp.Body.Close() - var result RootGenerationStatusResponse + var result GenerateRootStatusResponse err = resp.DecodeJSON(&result) return &result, err } -type RootGenerationStatusResponse struct { +type GenerateRootStatusResponse struct { Nonce string Started bool Progress int diff --git a/command/generate-root.go b/command/generate-root.go index 2d85424f1c..c20cedb03c 100644 --- a/command/generate-root.go +++ b/command/generate-root.go @@ -75,7 +75,7 @@ func (c *GenerateRootCommand) Run(args []string) int { } // Check if the root generation is started - rootGenerationStatus, err := client.Sys().RootGenerationStatus() + rootGenerationStatus, err := client.Sys().GenerateRootStatus() if err != nil { c.Ui.Error(fmt.Sprintf("Error reading root generation status: %s", err)) return 1 @@ -131,21 +131,21 @@ func (c *GenerateRootCommand) Run(args []string) int { // Check if we are running doing any restricted variants switch { case init: - return c.initRootGeneration(client, otp, pgpKey) + return c.initGenerateRoot(client, otp, pgpKey) case cancel: - return c.cancelRootGeneration(client) + return c.cancelGenerateRoot(client) case status: return c.rootGenerationStatus(client) } // Start the root generation process if not started if !rootGenerationStatus.Started { - err = client.Sys().RootGenerationInit(otp, pgpKey) + err = client.Sys().GenerateRootInit(otp, pgpKey) if err != nil { c.Ui.Error(fmt.Sprintf("Error initializing root generation: %s", err)) return 1 } - rootGenerationStatus, err = client.Sys().RootGenerationStatus() + rootGenerationStatus, err = client.Sys().GenerateRootStatus() if err != nil { c.Ui.Error(fmt.Sprintf("Error reading root generation status: %s", err)) return 1 @@ -182,7 +182,7 @@ func (c *GenerateRootCommand) Run(args []string) int { } // Provide the key, this may potentially complete the update - statusResp, err := client.Sys().RootGenerationUpdate(strings.TrimSpace(key), c.Nonce) + statusResp, err := client.Sys().GenerateRootUpdate(strings.TrimSpace(key), c.Nonce) if err != nil { c.Ui.Error(fmt.Sprintf("Error attempting generate-root update: %s", err)) return 1 @@ -226,10 +226,10 @@ func (c *GenerateRootCommand) decode(encodedVal, otp string) int { return 0 } -// initRootGeneration is used to start the generation process -func (c *GenerateRootCommand) initRootGeneration(client *api.Client, otp string, pgpKey string) int { +// initGenerateRoot is used to start the generation process +func (c *GenerateRootCommand) initGenerateRoot(client *api.Client, otp string, pgpKey string) int { // Start the rekey - err := client.Sys().RootGenerationInit(otp, pgpKey) + err := client.Sys().GenerateRootInit(otp, pgpKey) if err != nil { c.Ui.Error(fmt.Sprintf("Error initializing root generation: %s", err)) return 1 @@ -239,9 +239,9 @@ func (c *GenerateRootCommand) initRootGeneration(client *api.Client, otp string, return c.rootGenerationStatus(client) } -// cancelRootGeneration is used to abort the generation process -func (c *GenerateRootCommand) cancelRootGeneration(client *api.Client) int { - err := client.Sys().RootGenerationCancel() +// cancelGenerateRoot is used to abort the generation process +func (c *GenerateRootCommand) cancelGenerateRoot(client *api.Client) int { + err := client.Sys().GenerateRootCancel() if err != nil { c.Ui.Error(fmt.Sprintf("Failed to cancel root generation: %s", err)) return 1 @@ -253,7 +253,7 @@ func (c *GenerateRootCommand) cancelRootGeneration(client *api.Client) int { // rootGenerationStatus is used just to fetch and dump the status func (c *GenerateRootCommand) rootGenerationStatus(client *api.Client) int { // Check the status - status, err := client.Sys().RootGenerationStatus() + status, err := client.Sys().GenerateRootStatus() if err != nil { c.Ui.Error(fmt.Sprintf("Error reading root generation status: %s", err)) return 1 @@ -265,7 +265,7 @@ func (c *GenerateRootCommand) rootGenerationStatus(client *api.Client) int { } // dumpStatus dumps the status to output -func (c *GenerateRootCommand) dumpStatus(status *api.RootGenerationStatusResponse) { +func (c *GenerateRootCommand) dumpStatus(status *api.GenerateRootStatusResponse) { // Dump the status statString := fmt.Sprintf( "Nonce: %s\n"+ diff --git a/command/generate-root_test.go b/command/generate-root_test.go index d319ab3cda..87bea42d73 100644 --- a/command/generate-root_test.go +++ b/command/generate-root_test.go @@ -29,7 +29,7 @@ func TestGenerateRoot_Cancel(t *testing.T) { }, } - otpBytes, err := xor.GenerateRandBytes(16) + otpBytes, err := vault.GenerateRandBytes(16) if err != nil { t.Fatal(err) } @@ -45,7 +45,7 @@ func TestGenerateRoot_Cancel(t *testing.T) { t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) } - config, err := core.RootGenerationConfiguration() + config, err := core.GenerateRootConfiguration() if err != nil { t.Fatalf("err: %s", err) } @@ -67,7 +67,7 @@ func TestGenerateRoot_status(t *testing.T) { }, } - otpBytes, err := xor.GenerateRandBytes(16) + otpBytes, err := vault.GenerateRandBytes(16) if err != nil { t.Fatal(err) } @@ -102,7 +102,7 @@ func TestGenerateRoot_OTP(t *testing.T) { } // Generate an OTP - otpBytes, err := xor.GenerateRandBytes(16) + otpBytes, err := vault.GenerateRandBytes(16) if err != nil { t.Fatal(err) } @@ -118,7 +118,7 @@ func TestGenerateRoot_OTP(t *testing.T) { t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) } - config, err := core.RootGenerationConfiguration() + config, err := core.GenerateRootConfiguration() if err != nil { t.Fatalf("err: %v", err) } @@ -202,7 +202,7 @@ func TestGenerateRoot_PGP(t *testing.T) { t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) } - config, err := core.RootGenerationConfiguration() + config, err := core.GenerateRootConfiguration() if err != nil { t.Fatalf("err: %v", err) } diff --git a/helper/xor/xor_test.go b/helper/xor/xor_test.go index 2139d9166c..f50f525ce6 100644 --- a/helper/xor/xor_test.go +++ b/helper/xor/xor_test.go @@ -1,9 +1,7 @@ package xor import ( - "crypto/rand" "encoding/base64" - "fmt" "testing" ) @@ -13,27 +11,6 @@ const ( expectedB64 = "7AmkVw0p6ksamAwv19BVuA==" ) -func GenerateRandBytes(length int) ([]byte, error) { - if length < 0 { - return nil, fmt.Errorf("length must be >= 0") - } - - buf := make([]byte, length) - if length == 0 { - return buf, nil - } - - n, err := rand.Read(buf) - if err != nil { - return nil, err - } - if n != length { - return nil, fmt.Errorf("unable to read %d bytes; only read %d", length, n) - } - - return buf, nil -} - func TestBase64XOR(t *testing.T) { ret, err := XORBase64(tokenB64, xorB64) if err != nil { diff --git a/http/handler.go b/http/handler.go index 3f0728268e..bd2f2dafc7 100644 --- a/http/handler.go +++ b/http/handler.go @@ -41,8 +41,8 @@ func Handler(core *vault.Core) http.Handler { mux.Handle("/v1/sys/health", handleSysHealth(core)) mux.Handle("/v1/sys/rotate", proxySysRequest(core)) mux.Handle("/v1/sys/key-status", proxySysRequest(core)) - mux.Handle("/v1/sys/root-generation/attempt", handleSysRootGenerationInit(core)) - mux.Handle("/v1/sys/root-generation/update", handleSysRootGenerationUpdate(core)) + mux.Handle("/v1/sys/generate-root/attempt", handleSysGenerateRootAttempt(core)) + mux.Handle("/v1/sys/generate-root/update", handleSysGenerateRootUpdate(core)) mux.Handle("/v1/sys/rekey/init", handleSysRekeyInit(core)) mux.Handle("/v1/sys/rekey/backup", proxySysRequest(core)) mux.Handle("/v1/sys/rekey/update", handleSysRekeyUpdate(core)) diff --git a/http/sys_root_generation.go b/http/sys_generate_root.go similarity index 73% rename from http/sys_root_generation.go rename to http/sys_generate_root.go index a5c8c0289c..564b8e2b3d 100644 --- a/http/sys_root_generation.go +++ b/http/sys_generate_root.go @@ -9,22 +9,22 @@ import ( "github.com/hashicorp/vault/vault" ) -func handleSysRootGenerationInit(core *vault.Core) http.Handler { +func handleSysGenerateRootAttempt(core *vault.Core) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch r.Method { case "GET": - handleSysRootGenerationInitGet(core, w, r) + handleSysGenerateRootAttemptGet(core, w, r) case "POST", "PUT": - handleSysRootGenerationInitPut(core, w, r) + handleSysGenerateRootAttemptPut(core, w, r) case "DELETE": - handleSysRootGenerationInitDelete(core, w, r) + handleSysGenerateRootAttemptDelete(core, w, r) default: respondError(w, http.StatusMethodNotAllowed, nil) } }) } -func handleSysRootGenerationInitGet(core *vault.Core, w http.ResponseWriter, r *http.Request) { +func handleSysGenerateRootAttemptGet(core *vault.Core, w http.ResponseWriter, r *http.Request) { // Get the current seal configuration sealConfig, err := core.SealConfig() if err != nil { @@ -38,21 +38,21 @@ func handleSysRootGenerationInitGet(core *vault.Core, w http.ResponseWriter, r * } // Get the generation configuration - generationConfig, err := core.RootGenerationConfiguration() + generationConfig, err := core.GenerateRootConfiguration() if err != nil { respondError(w, http.StatusInternalServerError, err) return } // Get the progress - progress, err := core.RootGenerationProgress() + progress, err := core.GenerateRootProgress() if err != nil { respondError(w, http.StatusInternalServerError, err) return } // Format the status - status := &RootGenerationStatusResponse{ + status := &GenerateRootStatusResponse{ Started: false, Progress: progress, Required: sealConfig.SecretThreshold, @@ -67,9 +67,9 @@ func handleSysRootGenerationInitGet(core *vault.Core, w http.ResponseWriter, r * respondOk(w, status) } -func handleSysRootGenerationInitPut(core *vault.Core, w http.ResponseWriter, r *http.Request) { +func handleSysGenerateRootAttemptPut(core *vault.Core, w http.ResponseWriter, r *http.Request) { // Parse the request - var req RootGenerationInitRequest + var req GenerateRootInitRequest if err := parseRequest(r, &req); err != nil { respondError(w, http.StatusBadRequest, err) return @@ -80,8 +80,8 @@ func handleSysRootGenerationInitPut(core *vault.Core, w http.ResponseWriter, r * return } - // Initialize the generation - err := core.RootGenerationInit(req.OTP, req.PGPKey) + // Attemptialize the generation + err := core.GenerateRootInit(req.OTP, req.PGPKey) if err != nil { respondError(w, http.StatusBadRequest, err) return @@ -89,8 +89,8 @@ func handleSysRootGenerationInitPut(core *vault.Core, w http.ResponseWriter, r * respondOk(w, nil) } -func handleSysRootGenerationInitDelete(core *vault.Core, w http.ResponseWriter, r *http.Request) { - err := core.RootGenerationCancel() +func handleSysGenerateRootAttemptDelete(core *vault.Core, w http.ResponseWriter, r *http.Request) { + err := core.GenerateRootCancel() if err != nil { respondError(w, http.StatusInternalServerError, err) return @@ -98,10 +98,10 @@ func handleSysRootGenerationInitDelete(core *vault.Core, w http.ResponseWriter, respondOk(w, nil) } -func handleSysRootGenerationUpdate(core *vault.Core) http.Handler { +func handleSysGenerateRootUpdate(core *vault.Core) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Parse the request - var req RootGenerationUpdateRequest + var req GenerateRootUpdateRequest if err := parseRequest(r, &req); err != nil { respondError(w, http.StatusBadRequest, err) return @@ -123,13 +123,13 @@ func handleSysRootGenerationUpdate(core *vault.Core) http.Handler { } // Use the key to make progress on root generation - result, err := core.RootGenerationUpdate(key, req.Nonce) + result, err := core.GenerateRootUpdate(key, req.Nonce) if err != nil { respondError(w, http.StatusBadRequest, err) return } - resp := &RootGenerationStatusResponse{ + resp := &GenerateRootStatusResponse{ Complete: result.Progress == result.Required, Nonce: req.Nonce, Progress: result.Progress, @@ -143,12 +143,12 @@ func handleSysRootGenerationUpdate(core *vault.Core) http.Handler { }) } -type RootGenerationInitRequest struct { +type GenerateRootInitRequest struct { OTP string `json:"otp"` PGPKey string `json:"pgp_key"` } -type RootGenerationStatusResponse struct { +type GenerateRootStatusResponse struct { Nonce string `json:"nonce"` Started bool `json:"started"` Progress int `json:"progress"` @@ -158,7 +158,7 @@ type RootGenerationStatusResponse struct { PGPFingerprint string `json:"pgp_fingerprint"` } -type RootGenerationUpdateRequest struct { +type GenerateRootUpdateRequest struct { Nonce string Key string } diff --git a/http/sys_root_generation_test.go b/http/sys_generate_root_test.go similarity index 79% rename from http/sys_root_generation_test.go rename to http/sys_generate_root_test.go index 3bb5b04b20..35c0cb3e4a 100644 --- a/http/sys_root_generation_test.go +++ b/http/sys_generate_root_test.go @@ -13,13 +13,13 @@ import ( "github.com/hashicorp/vault/vault" ) -func TestSysRootGenerationInit_Status(t *testing.T) { +func TestSysGenerateRootAttempt_Status(t *testing.T) { core, _, token := vault.TestCoreUnsealed(t) ln, addr := TestServer(t, core) defer ln.Close() TestServerAuth(t, addr, token) - resp, err := http.Get(addr + "/v1/sys/root-generation/attempt") + resp, err := http.Get(addr + "/v1/sys/generate-root/attempt") if err != nil { t.Fatalf("err: %s", err) } @@ -41,24 +41,24 @@ func TestSysRootGenerationInit_Status(t *testing.T) { } } -func TestSysRootGenerationInit_Setup_OTP(t *testing.T) { +func TestSysGenerateRootAttempt_Setup_OTP(t *testing.T) { core, _, token := vault.TestCoreUnsealed(t) ln, addr := TestServer(t, core) defer ln.Close() TestServerAuth(t, addr, token) - otpBytes, err := xor.GenerateRandBytes(16) + otpBytes, err := vault.GenerateRandBytes(16) if err != nil { t.Fatal(err) } otp := base64.StdEncoding.EncodeToString(otpBytes) - resp := testHttpPut(t, token, addr+"/v1/sys/root-generation/attempt", map[string]interface{}{ + resp := testHttpPut(t, token, addr+"/v1/sys/generate-root/attempt", map[string]interface{}{ "otp": otp, }) testResponseStatus(t, resp, 204) - resp = testHttpGet(t, token, addr+"/v1/sys/root-generation/attempt") + resp = testHttpGet(t, token, addr+"/v1/sys/generate-root/attempt") var actual map[string]interface{} expected := map[string]interface{}{ @@ -77,18 +77,18 @@ func TestSysRootGenerationInit_Setup_OTP(t *testing.T) { } } -func TestSysRootGenerationInit_Setup_PGP(t *testing.T) { +func TestSysGenerateRootAttempt_Setup_PGP(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/root-generation/attempt", map[string]interface{}{ + resp := testHttpPut(t, token, addr+"/v1/sys/generate-root/attempt", map[string]interface{}{ "pgp_key": pgpkeys.TestPubKey1, }) testResponseStatus(t, resp, 204) - resp = testHttpGet(t, token, addr+"/v1/sys/root-generation/attempt") + resp = testHttpGet(t, token, addr+"/v1/sys/generate-root/attempt") var actual map[string]interface{} expected := map[string]interface{}{ @@ -107,26 +107,26 @@ func TestSysRootGenerationInit_Setup_PGP(t *testing.T) { } } -func TestSysRootGenerationInit_Cancel(t *testing.T) { +func TestSysGenerateRootAttempt_Cancel(t *testing.T) { core, _, token := vault.TestCoreUnsealed(t) ln, addr := TestServer(t, core) defer ln.Close() TestServerAuth(t, addr, token) - otpBytes, err := xor.GenerateRandBytes(16) + otpBytes, err := vault.GenerateRandBytes(16) if err != nil { t.Fatal(err) } otp := base64.StdEncoding.EncodeToString(otpBytes) - resp := testHttpPut(t, token, addr+"/v1/sys/root-generation/attempt", map[string]interface{}{ + resp := testHttpPut(t, token, addr+"/v1/sys/generate-root/attempt", map[string]interface{}{ "otp": otp, }) - resp = testHttpDelete(t, token, addr+"/v1/sys/root-generation/attempt") + resp = testHttpDelete(t, token, addr+"/v1/sys/generate-root/attempt") testResponseStatus(t, resp, 204) - resp, err = http.Get(addr + "/v1/sys/root-generation/attempt") + resp, err = http.Get(addr + "/v1/sys/generate-root/attempt") if err != nil { t.Fatalf("err: %s", err) } @@ -148,70 +148,70 @@ func TestSysRootGenerationInit_Cancel(t *testing.T) { } } -func TestSysRootGeneration_badKey(t *testing.T) { +func TestSysGenerateRoot_badKey(t *testing.T) { core, _, token := vault.TestCoreUnsealed(t) ln, addr := TestServer(t, core) defer ln.Close() TestServerAuth(t, addr, token) - otpBytes, err := xor.GenerateRandBytes(16) + otpBytes, err := vault.GenerateRandBytes(16) if err != nil { t.Fatal(err) } otp := base64.StdEncoding.EncodeToString(otpBytes) - resp := testHttpPut(t, token, addr+"/v1/sys/root-generation/update", map[string]interface{}{ + resp := testHttpPut(t, token, addr+"/v1/sys/generate-root/update", map[string]interface{}{ "key": "0123", "otp": otp, }) testResponseStatus(t, resp, 400) } -func TestSysRootGeneration_ReInitUpdate(t *testing.T) { +func TestSysGenerateRoot_ReAttemptUpdate(t *testing.T) { core, _, token := vault.TestCoreUnsealed(t) ln, addr := TestServer(t, core) defer ln.Close() TestServerAuth(t, addr, token) - otpBytes, err := xor.GenerateRandBytes(16) + otpBytes, err := vault.GenerateRandBytes(16) if err != nil { t.Fatal(err) } otp := base64.StdEncoding.EncodeToString(otpBytes) - resp := testHttpPut(t, token, addr+"/v1/sys/root-generation/attempt", map[string]interface{}{ + resp := testHttpPut(t, token, addr+"/v1/sys/generate-root/attempt", map[string]interface{}{ "otp": otp, }) testResponseStatus(t, resp, 204) - resp = testHttpDelete(t, token, addr+"/v1/sys/root-generation/attempt") + resp = testHttpDelete(t, token, addr+"/v1/sys/generate-root/attempt") testResponseStatus(t, resp, 204) - resp = testHttpPut(t, token, addr+"/v1/sys/root-generation/attempt", map[string]interface{}{ + resp = testHttpPut(t, token, addr+"/v1/sys/generate-root/attempt", map[string]interface{}{ "pgp_key": pgpkeys.TestPubKey1, }) testResponseStatus(t, resp, 204) } -func TestSysRootGeneration_Update_OTP(t *testing.T) { +func TestSysGenerateRoot_Update_OTP(t *testing.T) { core, master, token := vault.TestCoreUnsealed(t) ln, addr := TestServer(t, core) defer ln.Close() TestServerAuth(t, addr, token) - otpBytes, err := xor.GenerateRandBytes(16) + otpBytes, err := vault.GenerateRandBytes(16) if err != nil { t.Fatal(err) } otp := base64.StdEncoding.EncodeToString(otpBytes) - resp := testHttpPut(t, token, addr+"/v1/sys/root-generation/attempt", map[string]interface{}{ + resp := testHttpPut(t, token, addr+"/v1/sys/generate-root/attempt", map[string]interface{}{ "otp": otp, }) testResponseStatus(t, resp, 204) // We need to get the nonce first before we update - resp, err = http.Get(addr + "/v1/sys/root-generation/attempt") + resp, err = http.Get(addr + "/v1/sys/generate-root/attempt") if err != nil { t.Fatalf("err: %s", err) } @@ -219,7 +219,7 @@ func TestSysRootGeneration_Update_OTP(t *testing.T) { testResponseStatus(t, resp, 200) testResponseBody(t, resp, &rootGenerationStatus) - resp = testHttpPut(t, token, addr+"/v1/sys/root-generation/update", map[string]interface{}{ + resp = testHttpPut(t, token, addr+"/v1/sys/generate-root/update", map[string]interface{}{ "nonce": rootGenerationStatus["nonce"].(string), "key": hex.EncodeToString(master), }) @@ -277,19 +277,19 @@ func TestSysRootGeneration_Update_OTP(t *testing.T) { } } -func TestSysRootGeneration_Update_PGP(t *testing.T) { +func TestSysGenerateRoot_Update_PGP(t *testing.T) { core, master, token := vault.TestCoreUnsealed(t) ln, addr := TestServer(t, core) defer ln.Close() TestServerAuth(t, addr, token) - resp := testHttpPut(t, token, addr+"/v1/sys/root-generation/attempt", map[string]interface{}{ + resp := testHttpPut(t, token, addr+"/v1/sys/generate-root/attempt", map[string]interface{}{ "pgp_key": pgpkeys.TestPubKey1, }) testResponseStatus(t, resp, 204) // We need to get the nonce first before we update - resp, err := http.Get(addr + "/v1/sys/root-generation/attempt") + resp, err := http.Get(addr + "/v1/sys/generate-root/attempt") if err != nil { t.Fatalf("err: %s", err) } @@ -297,7 +297,7 @@ func TestSysRootGeneration_Update_PGP(t *testing.T) { testResponseStatus(t, resp, 200) testResponseBody(t, resp, &rootGenerationStatus) - resp = testHttpPut(t, token, addr+"/v1/sys/root-generation/update", map[string]interface{}{ + resp = testHttpPut(t, token, addr+"/v1/sys/generate-root/update", map[string]interface{}{ "nonce": rootGenerationStatus["nonce"].(string), "key": hex.EncodeToString(master), }) diff --git a/vault/core.go b/vault/core.go index fc0b5ed8a8..1cd4f782ba 100644 --- a/vault/core.go +++ b/vault/core.go @@ -214,11 +214,11 @@ type Core struct { // the threshold number of parts is available. unlockParts [][]byte - // rootGenerationProgress holds the shares until we reach enough + // generateRootProgress holds the shares until we reach enough // to verify the master key - rootGenerationConfig *RootGenerationConfig - rootGenerationProgress [][]byte - rootGenerationLock sync.Mutex + generateRootConfig *GenerateRootConfig + generateRootProgress [][]byte + generateRootLock sync.Mutex // rekeyProgress holds the shares we have until we reach enough // to verify the master key. diff --git a/vault/root_generation.go b/vault/generate_root.go similarity index 66% rename from vault/root_generation.go rename to vault/generate_root.go index 2f1375d617..a823260ddf 100644 --- a/vault/root_generation.go +++ b/vault/generate_root.go @@ -12,26 +12,26 @@ import ( "github.com/hashicorp/vault/shamir" ) -// RootGenerationConfig holds the configuration for a root generation +// GenerateRootConfig holds the configuration for a root generation // command. -type RootGenerationConfig struct { +type GenerateRootConfig struct { Nonce string PGPKey string PGPFingerprint string OTP string } -// RootGenerationResult holds the result of a root generation update +// GenerateRootResult holds the result of a root generation update // command -type RootGenerationResult struct { +type GenerateRootResult struct { Progress int Required int EncodedRootToken string PGPFingerprint string } -// RootGeneration is used to return the root generation progress (num shares) -func (c *Core) RootGenerationProgress() (int, error) { +// GenerateRoot is used to return the root generation progress (num shares) +func (c *Core) GenerateRootProgress() (int, error) { c.stateLock.RLock() defer c.stateLock.RUnlock() if c.sealed { @@ -41,15 +41,15 @@ func (c *Core) RootGenerationProgress() (int, error) { return 0, ErrStandby } - c.rootGenerationLock.Lock() - defer c.rootGenerationLock.Unlock() + c.generateRootLock.Lock() + defer c.generateRootLock.Unlock() - return len(c.rootGenerationProgress), nil + return len(c.generateRootProgress), nil } -// RootGenerationConfig is used to read the root generation configuration +// GenerateRootConfig is used to read the root generation configuration // It stubbornly refuses to return the OTP if one is there. -func (c *Core) RootGenerationConfiguration() (*RootGenerationConfig, error) { +func (c *Core) GenerateRootConfiguration() (*GenerateRootConfig, error) { c.stateLock.RLock() defer c.stateLock.RUnlock() if c.sealed { @@ -59,21 +59,21 @@ func (c *Core) RootGenerationConfiguration() (*RootGenerationConfig, error) { return nil, ErrStandby } - c.rootGenerationLock.Lock() - defer c.rootGenerationLock.Unlock() + c.generateRootLock.Lock() + defer c.generateRootLock.Unlock() // Copy the config if any - var conf *RootGenerationConfig - if c.rootGenerationConfig != nil { - conf = new(RootGenerationConfig) - *conf = *c.rootGenerationConfig + var conf *GenerateRootConfig + if c.generateRootConfig != nil { + conf = new(GenerateRootConfig) + *conf = *c.generateRootConfig conf.OTP = "" } return conf, nil } -// RootGenerationInit is used to initialize the root generation settings -func (c *Core) RootGenerationInit(otp, pgpKey string) error { +// GenerateRootInit is used to initialize the root generation settings +func (c *Core) GenerateRootInit(otp, pgpKey string) error { var fingerprint string switch { case len(otp) > 0: @@ -108,11 +108,11 @@ func (c *Core) RootGenerationInit(otp, pgpKey string) error { return ErrStandby } - c.rootGenerationLock.Lock() - defer c.rootGenerationLock.Unlock() + c.generateRootLock.Lock() + defer c.generateRootLock.Unlock() // Prevent multiple concurrent root generations - if c.rootGenerationConfig != nil { + if c.generateRootConfig != nil { return fmt.Errorf("root generation already in progress") } @@ -122,7 +122,7 @@ func (c *Core) RootGenerationInit(otp, pgpKey string) error { return err } - c.rootGenerationConfig = &RootGenerationConfig{ + c.generateRootConfig = &GenerateRootConfig{ Nonce: generationNonce, OTP: otp, PGPKey: pgpKey, @@ -130,12 +130,12 @@ func (c *Core) RootGenerationInit(otp, pgpKey string) error { } c.logger.Printf("[INFO] core: root generation initialized (nonce: %s)", - c.rootGenerationConfig.Nonce) + c.generateRootConfig.Nonce) return nil } -// RootGenerationUpdate is used to provide a new key part -func (c *Core) RootGenerationUpdate(key []byte, nonce string) (*RootGenerationResult, error) { +// GenerateRootUpdate is used to provide a new key part +func (c *Core) GenerateRootUpdate(key []byte, nonce string) (*GenerateRootResult, error) { // Verify the key length min, max := c.barrier.KeyLength() max += shamir.ShareOverhead @@ -167,48 +167,48 @@ func (c *Core) RootGenerationUpdate(key []byte, nonce string) (*RootGenerationRe return nil, ErrStandby } - c.rootGenerationLock.Lock() - defer c.rootGenerationLock.Unlock() + c.generateRootLock.Lock() + defer c.generateRootLock.Unlock() - // Ensure a rootGeneration is in progress - if c.rootGenerationConfig == nil { + // Ensure a generateRoot is in progress + if c.generateRootConfig == nil { return nil, fmt.Errorf("no root generation in progress") } - if nonce != c.rootGenerationConfig.Nonce { - return nil, fmt.Errorf("incorrect nonce supplied; nonce for this root generation operation is %s", c.rootGenerationConfig.Nonce) + if nonce != c.generateRootConfig.Nonce { + return nil, fmt.Errorf("incorrect nonce supplied; nonce for this root generation operation is %s", c.generateRootConfig.Nonce) } // Check if we already have this piece - for _, existing := range c.rootGenerationProgress { + for _, existing := range c.generateRootProgress { if bytes.Equal(existing, key) { return nil, nil } } // Store this key - c.rootGenerationProgress = append(c.rootGenerationProgress, key) - progress := len(c.rootGenerationProgress) + c.generateRootProgress = append(c.generateRootProgress, key) + progress := len(c.generateRootProgress) // Check if we don't have enough keys to unlock - if len(c.rootGenerationProgress) < config.SecretThreshold { + if len(c.generateRootProgress) < config.SecretThreshold { c.logger.Printf("[DEBUG] core: cannot generate root, have %d of %d keys", progress, config.SecretThreshold) - return &RootGenerationResult{ + return &GenerateRootResult{ Progress: progress, Required: config.SecretThreshold, - PGPFingerprint: c.rootGenerationConfig.PGPFingerprint, + PGPFingerprint: c.generateRootConfig.PGPFingerprint, }, nil } // Recover the master key var masterKey []byte if config.SecretThreshold == 1 { - masterKey = c.rootGenerationProgress[0] - c.rootGenerationProgress = nil + masterKey = c.generateRootProgress[0] + c.generateRootProgress = nil } else { - masterKey, err = shamir.Combine(c.rootGenerationProgress) - c.rootGenerationProgress = nil + masterKey, err = shamir.Combine(c.generateRootProgress) + c.generateRootProgress = nil if err != nil { return nil, fmt.Errorf("failed to compute master key: %v", err) } @@ -237,17 +237,17 @@ func (c *Core) RootGenerationUpdate(key []byte, nonce string) (*RootGenerationRe // Get the encoded value first so that if there is an error we don't create // the root token. switch { - case len(c.rootGenerationConfig.OTP) > 0: + case len(c.generateRootConfig.OTP) > 0: // This function performs decoding checks so rather than decode the OTP, // just encode the value we're passing in. - tokenBytes, err = xor.XORBase64(c.rootGenerationConfig.OTP, base64.StdEncoding.EncodeToString(buf)) + tokenBytes, err = xor.XORBase64(c.generateRootConfig.OTP, base64.StdEncoding.EncodeToString(buf)) if err != nil { c.logger.Printf("[ERR] core: xor of root token failed: %v", err) return nil, err } - case len(c.rootGenerationConfig.PGPKey) > 0: - _, tokenBytesArr, err := pgpkeys.EncryptShares([][]byte{[]byte(uuidStr)}, []string{c.rootGenerationConfig.PGPKey}) + case len(c.generateRootConfig.PGPKey) > 0: + _, tokenBytesArr, err := pgpkeys.EncryptShares([][]byte{[]byte(uuidStr)}, []string{c.generateRootConfig.PGPKey}) if err != nil { c.logger.Printf("[ERR] core: error encrypting new root token: %v", err) return nil, err @@ -264,23 +264,23 @@ func (c *Core) RootGenerationUpdate(key []byte, nonce string) (*RootGenerationRe return nil, err } - results := &RootGenerationResult{ + results := &GenerateRootResult{ Progress: progress, Required: config.SecretThreshold, EncodedRootToken: base64.StdEncoding.EncodeToString(tokenBytes), - PGPFingerprint: c.rootGenerationConfig.PGPFingerprint, + PGPFingerprint: c.generateRootConfig.PGPFingerprint, } c.logger.Printf("[INFO] core: root generation finished (nonce: %s)", - c.rootGenerationConfig.Nonce) + c.generateRootConfig.Nonce) - c.rootGenerationProgress = nil - c.rootGenerationConfig = nil + c.generateRootProgress = nil + c.generateRootConfig = nil return results, nil } -// RootGenerationCancel is used to cancel an in-progress root generation -func (c *Core) RootGenerationCancel() error { +// GenerateRootCancel is used to cancel an in-progress root generation +func (c *Core) GenerateRootCancel() error { c.stateLock.RLock() defer c.stateLock.RUnlock() if c.sealed { @@ -290,11 +290,11 @@ func (c *Core) RootGenerationCancel() error { return ErrStandby } - c.rootGenerationLock.Lock() - defer c.rootGenerationLock.Unlock() + c.generateRootLock.Lock() + defer c.generateRootLock.Unlock() // Clear any progress or config - c.rootGenerationConfig = nil - c.rootGenerationProgress = nil + c.generateRootConfig = nil + c.generateRootProgress = nil return nil } diff --git a/vault/root_generation_test.go b/vault/generate_root_test.go similarity index 69% rename from vault/root_generation_test.go rename to vault/generate_root_test.go index 167f379edc..17664e2122 100644 --- a/vault/root_generation_test.go +++ b/vault/generate_root_test.go @@ -9,16 +9,16 @@ import ( "github.com/hashicorp/vault/helper/xor" ) -func TestCore_RootGeneration_Lifecycle(t *testing.T) { +func TestCore_GenerateRoot_Lifecycle(t *testing.T) { c, master, _ := TestCoreUnsealed(t) // Verify update not allowed - if _, err := c.RootGenerationUpdate(master, ""); err == nil { + if _, err := c.GenerateRootUpdate(master, ""); err == nil { t.Fatalf("no root generation in progress") } // Should be no progress - num, err := c.RootGenerationProgress() + num, err := c.GenerateRootProgress() if err != nil { t.Fatalf("err: %v", err) } @@ -27,7 +27,7 @@ func TestCore_RootGeneration_Lifecycle(t *testing.T) { } // Should be no config - conf, err := c.RootGenerationConfiguration() + conf, err := c.GenerateRootConfiguration() if err != nil { t.Fatalf("err: %v", err) } @@ -36,36 +36,36 @@ func TestCore_RootGeneration_Lifecycle(t *testing.T) { } // Cancel should be idempotent - err = c.RootGenerationCancel() + err = c.GenerateRootCancel() if err != nil { t.Fatalf("err: %v", err) } - otpBytes, err := xor.GenerateRandBytes(16) + otpBytes, err := GenerateRandBytes(16) if err != nil { t.Fatal(err) } // Start a root generation - err = c.RootGenerationInit(base64.StdEncoding.EncodeToString(otpBytes), "") + err = c.GenerateRootInit(base64.StdEncoding.EncodeToString(otpBytes), "") if err != nil { t.Fatalf("err: %v", err) } // Should get config - conf, err = c.RootGenerationConfiguration() + conf, err = c.GenerateRootConfiguration() if err != nil { t.Fatalf("err: %v", err) } // Cancel should be clear - err = c.RootGenerationCancel() + err = c.GenerateRootCancel() if err != nil { t.Fatalf("err: %v", err) } // Should be no config - conf, err = c.RootGenerationConfiguration() + conf, err = c.GenerateRootConfiguration() if err != nil { t.Fatalf("err: %v", err) } @@ -74,41 +74,41 @@ func TestCore_RootGeneration_Lifecycle(t *testing.T) { } } -func TestCore_RootGeneration_Init(t *testing.T) { +func TestCore_GenerateRoot_Init(t *testing.T) { c, _, _ := TestCoreUnsealed(t) - otpBytes, err := xor.GenerateRandBytes(16) + otpBytes, err := GenerateRandBytes(16) if err != nil { t.Fatal(err) } - err = c.RootGenerationInit(base64.StdEncoding.EncodeToString(otpBytes), "") + err = c.GenerateRootInit(base64.StdEncoding.EncodeToString(otpBytes), "") if err != nil { t.Fatalf("err: %v", err) } // Second should fail - err = c.RootGenerationInit("", pgpkeys.TestPubKey1) + err = c.GenerateRootInit("", pgpkeys.TestPubKey1) if err == nil { t.Fatalf("should fail") } } -func TestCore_RootGeneration_InvalidMaster(t *testing.T) { +func TestCore_GenerateRoot_InvalidMaster(t *testing.T) { c, master, _ := TestCoreUnsealed(t) - otpBytes, err := xor.GenerateRandBytes(16) + otpBytes, err := GenerateRandBytes(16) if err != nil { t.Fatal(err) } - err = c.RootGenerationInit(base64.StdEncoding.EncodeToString(otpBytes), "") + err = c.GenerateRootInit(base64.StdEncoding.EncodeToString(otpBytes), "") if err != nil { t.Fatalf("err: %v", err) } // Fetch new config with generated nonce - rgconf, err := c.RootGenerationConfiguration() + rgconf, err := c.GenerateRootConfiguration() if err != nil { t.Fatalf("err: %v", err) } @@ -118,49 +118,49 @@ func TestCore_RootGeneration_InvalidMaster(t *testing.T) { // Provide the master (invalid) master[0]++ - _, err = c.RootGenerationUpdate(master, rgconf.Nonce) + _, err = c.GenerateRootUpdate(master, rgconf.Nonce) if err == nil { t.Fatalf("expected error") } } -func TestCore_RootGeneration_InvalidNonce(t *testing.T) { +func TestCore_GenerateRoot_InvalidNonce(t *testing.T) { c, master, _ := TestCoreUnsealed(t) - otpBytes, err := xor.GenerateRandBytes(16) + otpBytes, err := GenerateRandBytes(16) if err != nil { t.Fatal(err) } - err = c.RootGenerationInit(base64.StdEncoding.EncodeToString(otpBytes), "") + err = c.GenerateRootInit(base64.StdEncoding.EncodeToString(otpBytes), "") if err != nil { t.Fatalf("err: %v", err) } // Provide the nonce (invalid) - _, err = c.RootGenerationUpdate(master, "abcd") + _, err = c.GenerateRootUpdate(master, "abcd") if err == nil { t.Fatalf("expected error") } } -func TestCore_RootGeneration_Update_OTP(t *testing.T) { +func TestCore_GenerateRoot_Update_OTP(t *testing.T) { c, master, _ := TestCoreUnsealed(t) - otpBytes, err := xor.GenerateRandBytes(16) + otpBytes, err := GenerateRandBytes(16) if err != nil { t.Fatal(err) } otp := base64.StdEncoding.EncodeToString(otpBytes) // Start a root generation - err = c.RootGenerationInit(otp, "") + err = c.GenerateRootInit(otp, "") if err != nil { t.Fatalf("err: %v", err) } // Fetch new config with generated nonce - rkconf, err := c.RootGenerationConfiguration() + rkconf, err := c.GenerateRootConfiguration() if err != nil { t.Fatalf("err: %v", err) } @@ -169,7 +169,7 @@ func TestCore_RootGeneration_Update_OTP(t *testing.T) { } // Provide the master - result, err := c.RootGenerationUpdate(master, rkconf.Nonce) + result, err := c.GenerateRootUpdate(master, rkconf.Nonce) if err != nil { t.Fatalf("err: %v", err) } @@ -180,7 +180,7 @@ func TestCore_RootGeneration_Update_OTP(t *testing.T) { encodedRootToken := result.EncodedRootToken // Should be no progress - num, err := c.RootGenerationProgress() + num, err := c.GenerateRootProgress() if err != nil { t.Fatalf("err: %v", err) } @@ -189,7 +189,7 @@ func TestCore_RootGeneration_Update_OTP(t *testing.T) { } // Should be no config - conf, err := c.RootGenerationConfiguration() + conf, err := c.GenerateRootConfiguration() if err != nil { t.Fatalf("err: %v", err) } @@ -220,17 +220,17 @@ func TestCore_RootGeneration_Update_OTP(t *testing.T) { } } -func TestCore_RootGeneration_Update_PGP(t *testing.T) { +func TestCore_GenerateRoot_Update_PGP(t *testing.T) { c, master, _ := TestCoreUnsealed(t) // Start a root generation - err := c.RootGenerationInit("", pgpkeys.TestPubKey1) + err := c.GenerateRootInit("", pgpkeys.TestPubKey1) if err != nil { t.Fatalf("err: %v", err) } // Fetch new config with generated nonce - rkconf, err := c.RootGenerationConfiguration() + rkconf, err := c.GenerateRootConfiguration() if err != nil { t.Fatalf("err: %v", err) } @@ -239,7 +239,7 @@ func TestCore_RootGeneration_Update_PGP(t *testing.T) { } // Provide the master - result, err := c.RootGenerationUpdate(master, rkconf.Nonce) + result, err := c.GenerateRootUpdate(master, rkconf.Nonce) if err != nil { t.Fatalf("err: %v", err) } @@ -250,7 +250,7 @@ func TestCore_RootGeneration_Update_PGP(t *testing.T) { encodedRootToken := result.EncodedRootToken // Should be no progress - num, err := c.RootGenerationProgress() + num, err := c.GenerateRootProgress() if err != nil { t.Fatalf("err: %v", err) } @@ -259,7 +259,7 @@ func TestCore_RootGeneration_Update_PGP(t *testing.T) { } // Should be no config - conf, err := c.RootGenerationConfiguration() + conf, err := c.GenerateRootConfiguration() if err != nil { t.Fatalf("err: %v", err) } diff --git a/vault/testing.go b/vault/testing.go index 62da80ffa6..d9f8a67ecc 100644 --- a/vault/testing.go +++ b/vault/testing.go @@ -2,6 +2,7 @@ package vault import ( "bytes" + "crypto/rand" "crypto/sha256" "fmt" "log" @@ -341,3 +342,24 @@ func (n *rawHTTP) System() logical.SystemView { func (n *rawHTTP) Cleanup() { // noop } + +func GenerateRandBytes(length int) ([]byte, error) { + if length < 0 { + return nil, fmt.Errorf("length must be >= 0") + } + + buf := make([]byte, length) + if length == 0 { + return buf, nil + } + + n, err := rand.Read(buf) + if err != nil { + return nil, err + } + if n != length { + return nil, fmt.Errorf("unable to read %d bytes; only read %d", length, n) + } + + return buf, nil +} diff --git a/website/source/docs/http/sys-root-generation.html.md b/website/source/docs/http/sys-generate-root.html.md similarity index 90% rename from website/source/docs/http/sys-root-generation.html.md rename to website/source/docs/http/sys-generate-root.html.md index dd7cb4b82c..c76e89cfb5 100644 --- a/website/source/docs/http/sys-root-generation.html.md +++ b/website/source/docs/http/sys-generate-root.html.md @@ -1,12 +1,12 @@ --- layout: "http" -page_title: "HTTP API: /sys/root-generation/" -sidebar_current: "docs-http-sys-root-generation" +page_title: "HTTP API: /sys/generate-root/" +sidebar_current: "docs-http-sys-generate-root" description: |- - The `/sys/root-generation/` endpoints are used to create a new root key for Vault. + The `/sys/generate-root/` endpoints are used to create a new root key for Vault. --- -# /sys/root-generation/attempt +# /sys/generate-root/attempt ## GET @@ -21,7 +21,7 @@ description: |-
GET
URL
-
`/sys/root-generation/attempt`
+
`/sys/generate-root/attempt`
Parameters
@@ -65,7 +65,7 @@ description: |-
PUT
URL
-
`/sys/root-generation/attempt`
+
`/sys/generate-root/attempt`
Parameters
@@ -118,7 +118,7 @@ description: |-
DELETE
URL
-
`/sys/root-generation/attempt`
+
`/sys/generate-root/attempt`
Parameters
None @@ -129,7 +129,7 @@ description: |-
-# /sys/root-generation/update +# /sys/generate-root/update ## PUT @@ -147,7 +147,7 @@ description: |-
PUT
URL
-
`/sys/root-generation/update`
+
`/sys/generate-root/update`
Parameters
diff --git a/website/source/layouts/http.erb b/website/source/layouts/http.erb index b2afca54bf..ac69d5651e 100644 --- a/website/source/layouts/http.erb +++ b/website/source/layouts/http.erb @@ -22,8 +22,8 @@ > /sys/init - > - /sys/root-generation + > + /sys/generate-root