func handleSysGenerateRootUpdate(core *vault.Core) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Parse the request var req GenerateRootUpdateRequest if err := parseRequest(r, w, &req); err != nil { respondError(w, http.StatusBadRequest, err) return } if req.Key == "" { respondError( w, http.StatusBadRequest, errors.New("'key' must specified in request body as JSON")) return } // Decode the key, which is base64 or hex encoded min, max := core.BarrierKeyLength() key, err := hex.DecodeString(req.Key) // We check min and max here to ensure that a string that is base64 // encoded but also valid hex will not be valid and we instead base64 // decode it if err != nil || len(key) < min || len(key) > max { key, err = base64.StdEncoding.DecodeString(req.Key) if err != nil { respondError( w, http.StatusBadRequest, errors.New("'key' must be a valid hex or base64 string")) return } } // Use the key to make progress on root generation result, err := core.GenerateRootUpdate(key, req.Nonce) if err != nil { respondError(w, http.StatusBadRequest, err) return } resp := &GenerateRootStatusResponse{ Complete: result.Progress == result.Required, Nonce: req.Nonce, Progress: result.Progress, Required: result.Required, Started: true, EncodedRootToken: result.EncodedRootToken, PGPFingerprint: result.PGPFingerprint, } respondOk(w, resp) }) }
func handleSysUnseal(core *vault.Core) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch r.Method { case "PUT": case "POST": default: respondError(w, http.StatusMethodNotAllowed, nil) return } // Parse the request var req UnsealRequest if err := parseRequest(r, w, &req); err != nil { respondError(w, http.StatusBadRequest, err) return } if !req.Reset && req.Key == "" { respondError( w, http.StatusBadRequest, errors.New("'key' must specified in request body as JSON, or 'reset' set to true")) return } if req.Reset { sealed, err := core.Sealed() if err != nil { respondError(w, http.StatusInternalServerError, err) return } if !sealed { respondError(w, http.StatusBadRequest, errors.New("vault is unsealed")) return } core.ResetUnsealProcess() } else { // Decode the key, which is base64 or hex encoded min, max := core.BarrierKeyLength() key, err := hex.DecodeString(req.Key) // We check min and max here to ensure that a string that is base64 // encoded but also valid hex will not be valid and we instead base64 // decode it if err != nil || len(key) < min || len(key) > max { key, err = base64.StdEncoding.DecodeString(req.Key) if err != nil { respondError( w, http.StatusBadRequest, errors.New("'key' must be a valid hex or base64 string")) return } } // Attempt the unseal if _, err := core.Unseal(key); err != nil { switch { case errwrap.ContainsType(err, new(vault.ErrInvalidKey)): case errwrap.Contains(err, vault.ErrBarrierInvalidKey.Error()): case errwrap.Contains(err, vault.ErrBarrierNotInit.Error()): case errwrap.Contains(err, vault.ErrBarrierSealed.Error()): case errwrap.Contains(err, vault.ErrStandby.Error()): default: respondError(w, http.StatusInternalServerError, err) return } respondError(w, http.StatusBadRequest, err) return } } // Return the seal status handleSysSealStatusRaw(core, w, r) }) }
func handleSysRekeyUpdate(core *vault.Core, recovery bool) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { standby, _ := core.Standby() if standby { respondStandby(core, w, r.URL) return } // Parse the request var req RekeyUpdateRequest if err := parseRequest(r, w, &req); err != nil { respondError(w, http.StatusBadRequest, err) return } if req.Key == "" { respondError( w, http.StatusBadRequest, errors.New("'key' must specified in request body as JSON")) return } // Decode the key, which is base64 or hex encoded min, max := core.BarrierKeyLength() key, err := hex.DecodeString(req.Key) // We check min and max here to ensure that a string that is base64 // encoded but also valid hex will not be valid and we instead base64 // decode it if err != nil || len(key) < min || len(key) > max { key, err = base64.StdEncoding.DecodeString(req.Key) if err != nil { respondError( w, http.StatusBadRequest, errors.New("'key' must be a valid hex or base64 string")) return } } // Use the key to make progress on rekey result, err := core.RekeyUpdate(key, req.Nonce, recovery) if err != nil { respondError(w, http.StatusBadRequest, err) return } // Format the response resp := &RekeyUpdateResponse{} if result != nil { resp.Complete = true resp.Nonce = req.Nonce resp.Backup = result.Backup resp.PGPFingerprints = result.PGPFingerprints // Encode the keys keys := make([]string, 0, len(result.SecretShares)) keysB64 := make([]string, 0, len(result.SecretShares)) for _, k := range result.SecretShares { keys = append(keys, hex.EncodeToString(k)) keysB64 = append(keysB64, base64.StdEncoding.EncodeToString(k)) } resp.Keys = keys resp.KeysB64 = keysB64 } respondOk(w, resp) }) }