func (a *api) auth() bool { var err error k := new(secrets.Key) var secretKey string // Grab the credentials, look in the header first and fall back to the query string. if k.Name = a.req.Header.Get("X-Secret-ID"); k.Name == "" { k.Name = a.req.FormValue("secretid") } if secretKey = a.req.Header.Get("X-Secret-Key"); secretKey == "" { secretKey = a.req.FormValue("secretkey") } // If the master key has been used then just check the key, else check both. if k.Name == secrets.MasterKeyName { if secretKeyRegex.MatchString(secretKey) != true { log.Error("Invalid auth credential format.") return false } } else if secretIDRegex.MatchString(k.Name) != true || secretKeyRegex.MatchString(secretKey) != true { log.Error("Invalid auth credential format.") return false } a.keyID = k.Name a.key, err = base64.StdEncoding.DecodeString( secretKey) if err != nil { return false } priv := new([32]byte) pub := new([32]byte) copy(priv[:], a.key) defer secrets.Zero(priv[:]) err = database.GetKey(k) if err != nil { return false } if !k.ReadOnly { a.admin = true } curve25519.ScalarBaseMult(pub, priv) if subtle.ConstantTimeCompare(pub[:], k.Public) == 1 { return true } return false }
// 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) }