// UpdateSecret updates a secret by adding a new copy of it to the db. func (p *DB) UpdateSecret(s *secrets.Secret) error { if err := p.refresh(); err != nil { return err } // we need a new ID s.ID = 0 return p.addSecret(s) }
// GetSharedSecret returns the shared cert linking s and k func (p *DB) GetSharedSecret(s *secrets.Secret, k *secrets.Key) error { if err := p.refresh(); err != nil { return err } // We don't use a join due to conflicting columns err := p.GetKey(k) if err != nil { return err } s.Root = false s.KeyID = k.ID d := p.conn.Order("id asc").Find(s, s) if d.Error != nil { return d.Error } return p.conn.Find(&s.Key, s.KeyID).Error }
// Initialise should be run on first use of a new vault. func Initialise(w http.ResponseWriter, r *http.Request) { api := newAPI(w, r) defer api.req.Body.Close() // Check for an existing master secret master := new(secrets.Secret) master.Name = secrets.MasterKeyName err := database.GetRootSecret(master) switch err { case gorm.ErrRecordNotFound: break case nil: api.error("Vault already initialised", 409) return default: api.error("Database error", 500) return } key, err := secrets.Initialise() if err != nil { api.error("Error intialising master secret", 500) return } err = database.AddSecret(key) if err != nil { api.error("Database error", 500) return } log.Info("Vault initialised") api.reply(secrets.Key{ Name: key.Name, Key: key.Key.Display()}, 201) }
// Unseal opens the vault for writing func Unseal(w http.ResponseWriter, r *http.Request) { api := newAPI(w, r) defer api.req.Body.Close() if !api.auth() || !api.admin { api.error("Unauthorized", 401) return } master := new(secrets.Secret) master.Name = secrets.MasterKeyName err := database.GetRootSecret(master) switch err { case gorm.ErrRecordNotFound: api.error("Vault not initialised", 404) return case nil: break default: log.Error(err) api.error("Database error", 500) return } err = secrets.Unseal(master, api.key) if err != nil { api.error("Incorrect key for vault", 403) return } log.Info("Vault unsealed") api.message("OK", 200) return }
// GetRootSecret returns the latest matching root secret func (p *DB) GetRootSecret(s *secrets.Secret) error { if err := p.refresh(); err != nil { return err } s.Root = true d := p.conn.Order("id asc").Find(s, s) if d.Error != nil { return d.Error } return p.conn.Find(&s.Key, s.KeyID).Error }
func readDBcert() (cert []byte, err error) { root := new(secrets.Secret) shared := new(secrets.Secret) root.Name = certName shared.Name = certName key := new(secrets.Key) key.Name = certID priv, err := base64.StdEncoding.DecodeString(certKey) if err != nil { return } err = database.GetSharedSecret(shared, key) switch err { case gorm.ErrRecordNotFound: err = errors.New("Cert is not shared or does not exist") return case nil: break default: return } err = database.GetRootSecret(root) switch err { case gorm.ErrRecordNotFound: err = errors.New("Cert does not exist") return case nil: break default: return } return root.Decrypt(shared, priv) }
// Update changes the contents of a message but does not affect // which keys it is shared with func Update(w http.ResponseWriter, r *http.Request) { api := newAPI(w, r) defer api.req.Body.Close() if !api.auth() || !api.admin { api.error("Unauthorized", 401) return } request, err := api.read() if err != nil { log.Debug(err) api.error("Bad request", 400) return } if len(request.Message) == 0 { api.error("Missing elements in request", 400) return } if len(request.Name) == 0 { api.error("Missing elements in request", 400) return } secret := new(secrets.Secret) secret.Name = request.Name err = database.GetRootSecret(secret) switch err { case gorm.ErrRecordNotFound: api.error("Secret does not exist", 404) return case nil: break default: log.Error(err) api.error("Database error", 500) return } err = secret.Update([]byte(request.Message)) if err != nil { api.error("Server error", 500) return } err = database.UpdateSecret(secret) if err != nil { log.Error(err) api.error("Database error", 500) } else { log.Info("Secret updated: ", secret.Name) api.message("OK", 201) } return }
// View downloads a decrypted message func View(w http.ResponseWriter, r *http.Request) { api := newAPI(w, r) defer api.req.Body.Close() if !api.auth() { api.error("Unauthorized", 401) return } request, err := api.read() if err != nil { log.Debug(err) api.error("Bad request", 400) return } if name, ok := api.params["messageName"]; ok { request.Name = name } root := new(secrets.Secret) shared := new(secrets.Secret) root.Name = request.Name shared.Name = request.Name key := new(secrets.Key) key.Name = api.keyID err = database.GetSharedSecret(shared, key) switch err { case gorm.ErrRecordNotFound: api.error("Secret does not exist", 404) return case nil: break default: log.Error(err) api.error("Database error", 500) return } err = database.GetRootSecret(root) switch err { case gorm.ErrRecordNotFound: api.error("Secret does not exist", 404) return case nil: break default: log.Error(err) api.error("Database error", 500) return } message, err := root.Decrypt(shared, api.key) if err != nil { log.Debug(err) api.error("Cannot decrypt secret", 500) return } defer secrets.Zero(message) log.Info("Secret: ", shared.Name, " viewed by: ", key.Name) viewCount++ api.rawMessage(message, 200) }
// Share grants a key access to a message func Share(w http.ResponseWriter, r *http.Request) { api := newAPI(w, r) defer api.req.Body.Close() if !api.auth() || !api.admin { api.error("Unauthorized", 401) return } request, err := api.read() if err != nil { log.Debug(err) api.error("Bad request", 400) return } if len(request.KeyID) == 0 { api.error("Missing elements in request", 400) return } if len(request.Name) == 0 { api.error("Missing elements in request", 400) return } key := new(secrets.Key) key.Name = request.KeyID key.Key = request.Key err = database.GetKey(key) if err != nil { log.Error(err) api.error("Database error", 500) return } secret := new(secrets.Secret) secret.Name = request.Name err = database.GetRootSecret(secret) switch err { case gorm.ErrRecordNotFound: api.error("Secret does not exist", 404) return case nil: break default: log.Error(err) api.error("Database error", 500) return } shared, err := secret.Share(key) if err != nil { log.Error(err) api.error(err.Error(), 500) return } err = database.AddSecret(shared) if err != nil { log.Error(err) api.error("Database error", 500) return } log.Info("Secret: ", shared.Name, " shared with: ", key.Name) api.message("OK", 201) return }