Skip to content

Commit

Permalink
Add tamper history capabilities
Browse files Browse the repository at this point in the history
  • Loading branch information
iknite committed Dec 18, 2018
1 parent 2b5e1cd commit c55e1b3
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 106 deletions.
31 changes: 17 additions & 14 deletions api/tampering/tamper_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,12 @@ import (
"github.com/bbva/qed/hashing"
"github.com/bbva/qed/log"
"github.com/bbva/qed/storage"
"github.com/bbva/qed/util"
)

type tamperEvent struct {
Key []byte
Digest string
KeyDigest []byte
Value []byte
Digest string
Value string
}

// NewTamperingApi will return a mux server with the endpoint required to
Expand Down Expand Up @@ -67,28 +66,32 @@ func tamperFunc(store storage.DeletableStore, hasher hashing.Hasher) http.Handle
}

digest, _ := hex.DecodeString(tp.Digest)
tp.KeyDigest = digest
value, _ := hex.DecodeString(tp.Value)

switch r.Method {
case "PATCH":
get, err := store.Get(storage.IndexPrefix, tp.KeyDigest)
index, err := store.Get(storage.IndexPrefix, digest)
if err != nil {
http.Error(w, fmt.Sprintf("%s: %X", err.Error(), tp.Key), http.StatusUnprocessableEntity)
http.Error(w, fmt.Sprintf("%s: %X", err.Error(), index), http.StatusUnprocessableEntity)
return
}
log.Debugf("Get: %v", get)
mutations := make([]*storage.Mutation, 0)
mutations = append(mutations, storage.NewMutation(storage.IndexPrefix, tp.KeyDigest, tp.Value))

bIndex := make([]byte, 10) // Size of the index plus 2 bytes for the height
copy(bIndex, index.Value)
copy(bIndex[len(index.Value):], util.Uint16AsBytes(uint16(0)))

mutations := []*storage.Mutation{{storage.HistoryCachePrefix, bIndex, value}}

log.Debugf("Tamper: %v", store.Mutate(mutations))

case "DELETE":
get, err := store.Get(storage.IndexPrefix, tp.KeyDigest)
_, err = store.Get(storage.IndexPrefix, digest)
if err != nil {
http.Error(w, fmt.Sprintf("%s: %X", err.Error(), tp.Key), http.StatusUnprocessableEntity)
http.Error(w, fmt.Sprintf("%s: %X", err.Error(), digest), http.StatusUnprocessableEntity)
return
}
log.Debugf("Get: %v", get)
log.Debugf("Delete: %v", store.Delete(storage.IndexPrefix, tp.KeyDigest))

log.Debugf("Delete: %v", store.Delete(storage.IndexPrefix, digest))

}

Expand Down
6 changes: 4 additions & 2 deletions gossip/monitor/monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,10 @@ func (m *Monitor) executeTask(task *QueryTask) {
log.Debug("Executing task: %+v", task)
resp, err := m.client.Incremental(task.Start, task.End)
if err != nil {
// retry
log.Errorf("Error executing incremental query: %v", err)
// TODO: retry
m.sendAlert(fmt.Sprintf("Unable to verify incremental proof from %d to %d", task.Start, task.End))
log.Infof("Unable to verify incremental proof from %d to %d", task.Start, task.End)
return
}
ok := m.client.VerifyIncremental(resp, task.StartSnapshot, task.EndSnapshot, hashing.NewSha256Hasher())
if !ok {
Expand Down
184 changes: 99 additions & 85 deletions tests/e2e/agents_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@ package e2e

import (
"fmt"
"github.com/bbva/qed/hashing"
"io/ioutil"
"net/http"
"os/exec"
"strings"
"testing"
"time"

"github.com/bbva/qed/hashing"

"github.com/bbva/qed/protocol"
"github.com/bbva/qed/testutils/rand"
"github.com/bbva/qed/testutils/scope"
Expand Down Expand Up @@ -78,121 +79,134 @@ func TestAgents(t *testing.T) {
client := getClient(0)
event := rand.RandomString(10)

scenario("Add one event and check that it has been published without alerts", func() {
var snapshot *protocol.Snapshot
var ss *protocol.SignedSnapshot
var err error

let("Add event", func(t *testing.T) {
snapshot, err = client.Add(event)
assert.NoError(t, err)
time.Sleep(2 * time.Second)
})

let("Get signed snapshot from snapshot public storage", func(t *testing.T) {
time.Sleep(1 * time.Second)
ss, err = getSnapshot(0)
assert.NoError(t, err)
assert.Equal(t, snapshot, ss.Snapshot, "Snapshots must be equal")
})

let("Check Auditor do not create any alert", func(t *testing.T) {
time.Sleep(1 * time.Second)
alerts, err := getAlert()
assert.NoError(t, err)
assert.False(t, strings.Contains(string(alerts), "Unable to verify snapshot"), "Must not exist alerts")
})

let("Check Monitor do not create any alert", func(t *testing.T) {
time.Sleep(1 * time.Second)
alerts, err := getAlert()
assert.NoError(t, err)
assert.False(t, strings.Contains(string(alerts), "Unable to verify incremental"), "Must not exist alerts")
})

})
// scenario("Add one event and check that it has been published without alerts", func() {
// var snapshot *protocol.Snapshot
// var ss *protocol.SignedSnapshot
// var err error
//
// let("Add event", func(t *testing.T) {
// snapshot, err = client.Add(event)
// assert.NoError(t, err)
// time.Sleep(2 * time.Second)
// })
//
// let("Get signed snapshot from snapshot public storage", func(t *testing.T) {
// time.Sleep(1 * time.Second)
// ss, err = getSnapshot(0)
// assert.NoError(t, err)
// assert.Equal(t, snapshot, ss.Snapshot, "Snapshots must be equal")
// })
//
// let("Check Auditor do not create any alert", func(t *testing.T) {
// time.Sleep(1 * time.Second)
// alerts, err := getAlert()
// assert.NoError(t, err)
// assert.False(t, strings.Contains(string(alerts), "Unable to verify snapshot"), "Must not exist alerts")
// })
//
// let("Check Monitor do not create any alert", func(t *testing.T) {
// time.Sleep(1 * time.Second)
// alerts, err := getAlert()
// assert.NoError(t, err)
// assert.False(t, strings.Contains(string(alerts), "Unable to verify incremental"), "Must not exist alerts")
// })
//
// })
//
// scenario("Add 1st event. Tamper it. Check auditor alerts correctly", func() {
// var err error
//
// let("Add 1st event", func(t *testing.T) {
// _, err = client.Add(event)
// assert.NoError(t, err)
// time.Sleep(2 * time.Second)
// })
//
// let("Tamper 1st event", func(t *testing.T) {
// cmd := exec.Command("curl",
// "-sS",
// "-XDELETE",
// "-H", fmt.Sprintf("Api-Key:%s", APIKey),
// "-H", "Content-type: application/json",
// QEDTamperURL,
// "-d", fmt.Sprintf(`{"Digest": "%X"}`, hashing.NewSha256Hasher().Do(hashing.Digest(event))),
// )
//
// _, err := cmd.CombinedOutput()
// assert.NoError(t, err, "Subprocess must not exit with status 1")
// })
//
// let("Check Auditor alerts", func(t *testing.T) {
// time.Sleep(1 * time.Second)
// alerts, err := getAlert()
// assert.NoError(t, err)
// assert.True(t, strings.Contains(string(alerts), "Unable to verify snapshot"), "Must exist auditor alerts")
// })
//
// let("Check Monitor do not create any alert", func(t *testing.T) {
// time.Sleep(1 * time.Second)
// alerts, err := getAlert()
// assert.NoError(t, err)
// assert.False(t, strings.Contains(string(alerts), "Unable to verify incremental"), "Must not exist monitor alert")
// })
// })

scenario("Add 1st event. Tamper it. Check auditor alerts correctly", func() {
var err error
scenario("Add 1st event. Tamper it. Add 2nd event. Check monitor alerts correctly", func() {
hasher := hashing.NewSha256Hasher()
tampered := rand.RandomString(10)
event2 := rand.RandomString(10)

let("Add 1st event", func(t *testing.T) {
_, err = client.Add(event)
_, err := client.Add(event)
assert.NoError(t, err)
time.Sleep(2 * time.Second)
})

let("Tamper 1st event", func(t *testing.T) {
cmd := exec.Command("curl",
"-sS",
"-XDELETE",
"-H", fmt.Sprintf("Api-Key:%s", APIKey),
"-XPATCH",
"-H", fmt.Sprintf("Api-Key: %s", APIKey),
"-H", "Content-type: application/json",
QEDTamperURL,
"-d", fmt.Sprintf(`{"Digest": "%X"}`, hashing.NewSha256Hasher().Do(hashing.Digest(event))),
"-d", fmt.Sprintf(`{"Digest": "%X","Value": "%X"}`,
hasher.Do(hashing.Digest(event)),
hasher.Do(hashing.Digest(tampered)),
),
)

_, err := cmd.CombinedOutput()

assert.NoError(t, err, "Subprocess must not exit with status 1")
})

let("Check Auditor alerts", func(t *testing.T) {
let("Add 2nd event", func(t *testing.T) {
_, err := client.Add(event2)
assert.NoError(t, err)
time.Sleep(2 * time.Second)
})

let("Check Auditor do not create any alert", func(t *testing.T) {
alerts, err := getAlert()
assert.NoError(t, err)
assert.True(t, strings.Contains(string(alerts), "Unable to verify snapshot"), "Must exist auditor alerts")
assert.False(t, strings.Contains(string(alerts), "Unable to verify snapshot"), "Must not exist auditor alerts")
})

let("Check Monitor do not create any alert", func(t *testing.T) {
time.Sleep(1 * time.Second)
let("Check Monitor alert", func(t *testing.T) {
alerts, err := getAlert()
assert.NoError(t, err)
assert.False(t, strings.Contains(string(alerts), "Unable to verify incremental"), "Must not exist monitor alert")
assert.True(t, strings.Contains(string(alerts), "Unable to verify incremental"), "Must exist monitor alert")
})
})

// scenario("Add 1st event. Tamper it. Add 2nd event. Check monitor alerts correctly", func() {
// var err error
})

// scenario("Appendix B", func() {
//
// let("Add 1st event", func(t *testing.T) {
// _, err = client.Add(event)
// assert.NoError(t, err)
// })

// let("Tamper 1st event", func(t *testing.T) {
// cmd := exec.Command("curl",
// "-sS",
// "-XDELETE",
// "-H", fmt.Sprintf("Api-Key:%s", APIKey),
// "-H", "Content-type: application/json",
// QEDTamperURL,
// "-d", fmt.Sprintf(`{"Digest": "%X"}`, hashing.NewSha256Hasher().Do(hashing.Digest(event))),
// )

// o, err := cmd.CombinedOutput()
// fmt.Printf(">>>>>>>>>>>> %s %s\n", event, o)
// assert.NoError(t, err, "Subprocess must not exit with status 1")

// })

// event2 := rand.RandomString(10)
// let("Add 2nd event", func(t *testing.T) {
// _, err = client.Add(event2)
// assert.NoError(t, err)
// time.Sleep(2 * time.Second)
// })

// let("Check Auditor do not create any alert", func(t *testing.T) {
// time.Sleep(1 * time.Second)
// alerts, err := getAlert()
// assert.NoError(t, err)
// assert.False(t, strings.Contains(string(alerts), "Unable to verify snapshot"), "Must not exist auditor alerts")
// })

// let("Check Monitor alert", func(t *testing.T) {
// time.Sleep(1 * time.Second)
// alerts, err := getAlert()
// assert.NoError(t, err)
// assert.True(t, strings.Contains(string(alerts), "Unable to verify incremental"), "Must exist monitor alert")
// })

// })

}
5 changes: 4 additions & 1 deletion tests/e2e/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/bbva/qed/gossip/member"
"github.com/bbva/qed/gossip/monitor"
"github.com/bbva/qed/gossip/publisher"
"github.com/bbva/qed/log"
"github.com/bbva/qed/server"
"github.com/bbva/qed/testutils/scope"
)
Expand All @@ -50,6 +51,8 @@ func init() {

usr, _ := user.Current()
keyFile = fmt.Sprintf("%s/.ssh/id_ed25519", usr.HomeDir)

log.SetLogger("", log.SILENT)
}

// merge function is a helper function that execute all the variadic parameters
Expand All @@ -58,8 +61,8 @@ func merge(list ...scope.TestF) scope.TestF {
return func(t *testing.T) {
for _, elem := range list {
elem(t)
time.Sleep(2 * time.Second)
}
time.Sleep(2 * time.Second)
}
}

Expand Down
8 changes: 4 additions & 4 deletions tests/e2e/test_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"strconv"
"sync"
"sync/atomic"
"time"

"github.com/bbva/qed/log"
"github.com/bbva/qed/protocol"
)

Expand Down Expand Up @@ -234,11 +234,11 @@ func (s *Service) Start() {
select {
case <-ticker.C:
c := atomic.LoadUint64(&s.stats.count[RPS])
fmt.Println("Request per second: ", c)
fmt.Println("Counters ", s.stats.count)
log.Debugf("Request per second: ", c)
log.Debugf("Counters ", s.stats.count)
atomic.StoreUint64(&s.stats.count[RPS], 0)
case <-s.quitCh:
fmt.Println("\nShutting down the server...")
log.Debugf("\nShutting down the server...")
httpServer.Shutdown(context.Background())
return
}
Expand Down

0 comments on commit c55e1b3

Please sign in to comment.