func handleSysSealStatusRaw(core *vault.Core, w http.ResponseWriter, r *http.Request) { sealed, err := core.Sealed() if err != nil { respondError(w, http.StatusInternalServerError, err) return } sealConfig, err := core.SealAccess().BarrierConfig() if err != nil { respondError(w, http.StatusInternalServerError, err) return } if sealConfig == nil { respondError(w, http.StatusBadRequest, fmt.Errorf( "server is not yet initialized")) return } respondOk(w, &SealStatusResponse{ Sealed: sealed, T: sealConfig.SecretThreshold, N: sealConfig.SecretShares, Progress: core.SecretProgress(), }) }
func handleSysRekeyInitGet(core *vault.Core, recovery bool, w http.ResponseWriter, r *http.Request) { barrierConfig, err := core.SealAccess().BarrierConfig() if err != nil { respondError(w, http.StatusInternalServerError, err) return } if barrierConfig == nil { respondError(w, http.StatusBadRequest, fmt.Errorf( "server is not yet initialized")) return } // Get the rekey configuration rekeyConf, err := core.RekeyConfig(recovery) if err != nil { respondError(w, http.StatusInternalServerError, err) return } // Get the progress progress, err := core.RekeyProgress(recovery) if err != nil { respondError(w, http.StatusInternalServerError, err) return } sealThreshold, err := core.RekeyThreshold(recovery) if err != nil { respondError(w, http.StatusInternalServerError, err) return } // Format the status status := &RekeyStatusResponse{ Started: false, T: 0, N: 0, Progress: progress, Required: sealThreshold, } if rekeyConf != nil { status.Nonce = rekeyConf.Nonce status.Started = true status.T = rekeyConf.SecretThreshold status.N = rekeyConf.SecretShares if rekeyConf.PGPKeys != nil && len(rekeyConf.PGPKeys) != 0 { pgpFingerprints, err := pgpkeys.GetFingerprints(rekeyConf.PGPKeys, nil) if err != nil { respondError(w, http.StatusInternalServerError, err) return } status.PGPFingerprints = pgpFingerprints status.Backup = rekeyConf.Backup } } respondOk(w, status) }
func handleSysRekeyInit(core *vault.Core, recovery bool) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch { case recovery && !core.SealAccess().RecoveryKeySupported(): respondError(w, http.StatusBadRequest, fmt.Errorf("recovery rekeying not supported")) case r.Method == "GET": handleSysRekeyInitGet(core, recovery, w, r) case r.Method == "POST" || r.Method == "PUT": handleSysRekeyInitPut(core, recovery, w, r) case r.Method == "DELETE": handleSysRekeyInitDelete(core, recovery, w, r) default: respondError(w, http.StatusMethodNotAllowed, nil) } }) }
func handleSysSealStatusRaw(core *vault.Core, w http.ResponseWriter, r *http.Request) { sealed, err := core.Sealed() if err != nil { respondError(w, http.StatusInternalServerError, err) return } sealConfig, err := core.SealAccess().BarrierConfig() if err != nil { respondError(w, http.StatusInternalServerError, err) return } if sealConfig == nil { respondError(w, http.StatusBadRequest, fmt.Errorf( "server is not yet initialized")) return } // Fetch the local cluster name and identifier var clusterName, clusterID string if !sealed { cluster, err := core.Cluster() if err != nil { respondError(w, http.StatusInternalServerError, err) return } if cluster == nil { respondError(w, http.StatusInternalServerError, fmt.Errorf("failed to fetch cluster details")) return } clusterName = cluster.Name clusterID = cluster.ID } respondOk(w, &SealStatusResponse{ Sealed: sealed, T: sealConfig.SecretThreshold, N: sealConfig.SecretShares, Progress: core.SecretProgress(), Version: version.GetVersion().VersionNumber(), ClusterName: clusterName, ClusterID: clusterID, }) }
func handleSysRekeyInitPut(core *vault.Core, recovery bool, w http.ResponseWriter, r *http.Request) { // Parse the request var req RekeyRequest if err := parseRequest(r, &req); err != nil { respondError(w, http.StatusBadRequest, err) return } if req.Backup && len(req.PGPKeys) == 0 { respondError(w, http.StatusBadRequest, fmt.Errorf("cannot request a backup of the new keys without providing PGP keys for encryption")) return } // Right now we don't support this, but the rest of the code is ready for // when we do, hence the check below for this to be false if // StoredShares is greater than zero if core.SealAccess().StoredKeysSupported() { respondError(w, http.StatusBadRequest, fmt.Errorf("rekeying of barrier not supported when stored key support is available")) return } // Initialize the rekey err := core.RekeyInit(&vault.SealConfig{ SecretShares: req.SecretShares, SecretThreshold: req.SecretThreshold, StoredShares: req.StoredShares, PGPKeys: req.PGPKeys, Backup: req.Backup, }, recovery) if err != nil { respondError(w, http.StatusBadRequest, err) return } handleSysRekeyInitGet(core, recovery, w, r) }
func handleSysGenerateRootAttemptGet(core *vault.Core, w http.ResponseWriter, r *http.Request) { // Get the current seal configuration barrierConfig, err := core.SealAccess().BarrierConfig() if err != nil { respondError(w, http.StatusInternalServerError, err) return } if barrierConfig == nil { respondError(w, http.StatusBadRequest, fmt.Errorf( "server is not yet initialized")) return } sealConfig := barrierConfig if core.SealAccess().RecoveryKeySupported() { sealConfig, err = core.SealAccess().RecoveryConfig() if err != nil { respondError(w, http.StatusInternalServerError, err) return } } // Get the generation configuration generationConfig, err := core.GenerateRootConfiguration() if err != nil { respondError(w, http.StatusInternalServerError, err) return } // Get the progress progress, err := core.GenerateRootProgress() if err != nil { respondError(w, http.StatusInternalServerError, err) return } // Format the status status := &GenerateRootStatusResponse{ Started: false, Progress: progress, Required: sealConfig.SecretThreshold, Complete: false, } if generationConfig != nil { status.Nonce = generationConfig.Nonce status.Started = true status.PGPFingerprint = generationConfig.PGPFingerprint } respondOk(w, status) }
func handleSysInitPut(core *vault.Core, w http.ResponseWriter, r *http.Request) { // Parse the request var req InitRequest if err := parseRequest(r, &req); err != nil { respondError(w, http.StatusBadRequest, err) return } // Initialize barrierConfig := &vault.SealConfig{ SecretShares: req.SecretShares, SecretThreshold: req.SecretThreshold, StoredShares: req.StoredShares, PGPKeys: req.PGPKeys, } recoveryConfig := &vault.SealConfig{ SecretShares: req.RecoveryShares, SecretThreshold: req.RecoveryThreshold, PGPKeys: req.RecoveryPGPKeys, } 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 { respondError(w, http.StatusBadRequest, fmt.Errorf("PGP keys not supported when storing shares")) return } } else { if barrierConfig.StoredShares > 0 { respondError(w, http.StatusBadRequest, fmt.Errorf("stored keys are not supported")) return } } initParams := &vault.InitParams{ BarrierConfig: barrierConfig, RecoveryConfig: recoveryConfig, RootTokenPGPKey: req.RootTokenPGPKey, } result, initErr := core.Initialize(initParams) if initErr != nil { if !errwrap.ContainsType(initErr, new(vault.NonFatalError)) { respondError(w, http.StatusBadRequest, initErr) return } else { // Add a warnings field? The error will be logged in the vault log // already. } } // 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 := &InitResponse{ Keys: keys, KeysB64: keysB64, RootToken: result.RootToken, } if len(result.RecoveryShares) > 0 { resp.RecoveryKeys = make([]string, 0, len(result.RecoveryShares)) resp.RecoveryKeysB64 = make([]string, 0, len(result.RecoveryShares)) for _, k := range result.RecoveryShares { resp.RecoveryKeys = append(resp.RecoveryKeys, hex.EncodeToString(k)) resp.RecoveryKeysB64 = append(resp.RecoveryKeysB64, base64.StdEncoding.EncodeToString(k)) } } core.UnsealWithStoredKeys() respondOk(w, resp) }