Skip to content

Commit

Permalink
[WIP] Change monitoring request requirements
Browse files Browse the repository at this point in the history
  • Loading branch information
vqhuy committed Dec 9, 2016
1 parent 561f908 commit 0c5a61f
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 45 deletions.
48 changes: 24 additions & 24 deletions protocol/consistencychecks.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ import (
// subsequent responses from the ConiksDirectory to any
// client request.
type ConsistencyChecks struct {
// PinnedSTR stores the pinned signed tree root at epoch 0. This is hardcoded into the client.
PinnedSTR *m.SignedTreeRoot
// SavedSTR stores the latest verified signed tree root.
SavedSTR *m.SignedTreeRoot
// Bindings stores all the verified name-to-key bindings.
Expand All @@ -47,22 +45,17 @@ type ConsistencyChecks struct {
// TODO: maybe remove savedSTR from the parameters
// and have something like RestoreState(savedSTR, bindings, regepoch) instead.
// Possibly it somehow relate to #137 (client storage).
func NewCC(pinnedSTR, savedSTR *m.SignedTreeRoot, useTBs bool, signKey sign.PublicKey) *ConsistencyChecks {
func NewCC(savedSTR *m.SignedTreeRoot, useTBs bool, signKey sign.PublicKey) *ConsistencyChecks {
// TODO: see #110
if !useTBs {
panic("[coniks] Currently the server is forced to use TBs")
}
// TODO: this will break our test client
if pinnedSTR == nil {
panic("[coniks] ConsistencyChecks requires a pinned STR at epoch 0")
}
cc := &ConsistencyChecks{
PinnedSTR: pinnedSTR,
SavedSTR: savedSTR,
Bindings: make(map[string][]byte),
RegEpoch: make(map[string]uint64),
useTBs: useTBs,
signKey: signKey,
SavedSTR: savedSTR,
Bindings: make(map[string][]byte),
RegEpoch: make(map[string]uint64),
useTBs: useTBs,
signKey: signKey,
}
if useTBs {
cc.TBs = make(map[string]*TemporaryBinding)
Expand Down Expand Up @@ -141,14 +134,15 @@ func (cc *ConsistencyChecks) updateSTR(requestType int, msg *Response) error {
}

case MonitoringType:
// the requested epoch can be equal to saved epoch or the next expected epoch
// or epoch 0.
// the requested epoch can be equal to/or less than
// the saved epoch or the next expected epoch
strs := msg.DirectoryResponse.(*DirectoryProofs).STR
switch {
case strs[0].Epoch == 0: /* prior history verification */
if err := verifySTR(cc.PinnedSTR, strs[0]); err != nil {
return err
}
case strs[0].Epoch < cc.SavedSTR.Epoch: /* prior history verification */
// FIXME: TOFU until we introduce auditor modules?
// if err := verifySTR(???, strs[0]); err != nil {
// return err
// }
case strs[0].Epoch == cc.SavedSTR.Epoch:
if err := verifySTR(cc.SavedSTR, strs[0]); err != nil {
return err
Expand All @@ -158,15 +152,18 @@ func (cc *ConsistencyChecks) updateSTR(requestType int, msg *Response) error {
return err
}
default:
panic("[coniks] The next expected monitoring epochs should be read from SavedSTR.Epoch.")
panic("[coniks] The monitoring epochs cannot be greater than current the saved epoch")
}

for i := 1; i < len(strs); i++ {
if err := cc.verifySTRConsistency(strs[i-1], strs[i]); err != nil {
return err
}
}
str = strs[len(strs)-1]
str = cc.SavedSTR
if strs[len(strs)-1].Epoch > str.Epoch {
str = strs[len(strs)-1]
}

default:
panic("[coniks] Unknown request type")
Expand Down Expand Up @@ -273,9 +270,11 @@ func (cc *ConsistencyChecks) verifyMonitoring(msg *Response,
ap0 := dfs.AP[0]
regEp, ok := cc.RegEpoch[uname]

// TODO: is this actually faster?
wasUnameAbsent := ap0.ProofType() == m.ProofOfAbsence
switch {
case str0.Epoch == 0 && wasUnameAbsent: /* prior history verification */
case !ok && str0.Epoch < cc.SavedSTR.Epoch && wasUnameAbsent: /* prior history verification */
case ok && str0.Epoch < regEp && wasUnameAbsent: /* prior history verification */
case ok && str0.Epoch == regEp && wasUnameAbsent: /* registration epoch */
case ok && str0.Epoch >= regEp+1 && !wasUnameAbsent: /* after registration */
default:
Expand All @@ -289,8 +288,9 @@ func (cc *ConsistencyChecks) verifyMonitoring(msg *Response,
str := dfs.STR[i]
ap := dfs.AP[i]
switch {
case str0.Epoch == 0 && ap.ProofType() == m.ProofOfAbsence: /* prior history verification */
case str0.Epoch > 0 && ap.ProofType() == m.ProofOfInclusion:
case !ok && ap.ProofType() == m.ProofOfAbsence:
case str0.Epoch <= cc.SavedSTR.Epoch && ap.ProofType() == m.ProofOfAbsence: /* prior history verification */
case str0.Epoch > cc.SavedSTR.Epoch && ap.ProofType() == m.ProofOfInclusion:
default:
return CheckBadAuthPath
}
Expand Down
62 changes: 41 additions & 21 deletions protocol/consistencychecks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func TestVerifyWithError(t *testing.T) {
str.Signature = append([]byte{}, str.Signature...)
str.Signature[0]++

cc := NewCC(d.LatestSTR(), &str, true, pk)
cc := NewCC(&str, true, pk)

if e1, e2 := registerAndVerify(d, cc, alice, key); e1 != ReqSuccess || e2 != CheckBadSTR {
t.Error("Expect", ReqSuccess, "got", e1)
Expand All @@ -61,7 +61,7 @@ func TestVerifyWithError(t *testing.T) {

func TestMalformedClientMessage(t *testing.T) {
d, pk := NewTestDirectory(t, true)
cc := NewCC(d.LatestSTR(), d.LatestSTR(), true, pk)
cc := NewCC(d.LatestSTR(), true, pk)

request := &RegistrationRequest{
Username: "", // invalid username
Expand All @@ -75,7 +75,7 @@ func TestMalformedClientMessage(t *testing.T) {

func TestMalformedDirectoryMessage(t *testing.T) {
d, pk := NewTestDirectory(t, true)
cc := NewCC(d.LatestSTR(), d.LatestSTR(), true, pk)
cc := NewCC(d.LatestSTR(), true, pk)

request := &RegistrationRequest{
Username: "alice",
Expand All @@ -92,7 +92,7 @@ func TestMalformedDirectoryMessage(t *testing.T) {
func TestVerifyRegistrationResponseWithTB(t *testing.T) {
d, pk := NewTestDirectory(t, true)

cc := NewCC(d.LatestSTR(), d.LatestSTR(), true, pk)
cc := NewCC(d.LatestSTR(), true, pk)

if e1, e2 := registerAndVerify(d, cc, alice, key); e1 != ReqSuccess || e2 != CheckPassed {
t.Error(e1)
Expand Down Expand Up @@ -136,7 +136,7 @@ func TestVerifyRegistrationResponseWithTB(t *testing.T) {
func TestVerifyFullfilledPromise(t *testing.T) {
d, pk := NewTestDirectory(t, true)

cc := NewCC(d.LatestSTR(), d.LatestSTR(), true, pk)
cc := NewCC(d.LatestSTR(), true, pk)

if e1, e2 := registerAndVerify(d, cc, alice, key); e1 != ReqSuccess || e2 != CheckPassed {
t.Error(e1)
Expand Down Expand Up @@ -177,7 +177,7 @@ func TestVerifyFullfilledPromise(t *testing.T) {
func TestVerifyKeyLookupResponseWithTB(t *testing.T) {
d, pk := NewTestDirectory(t, true)

cc := NewCC(d.LatestSTR(), d.LatestSTR(), true, pk)
cc := NewCC(d.LatestSTR(), true, pk)

// do lookup first
if e1, e2 := lookupAndVerify(d, cc, alice, key); e1 != ReqNameNotFound || e2 != CheckPassed {
Expand Down Expand Up @@ -236,7 +236,7 @@ func TestVerifyKeyLookupResponseWithTB(t *testing.T) {

func TestVerifyTimeSkew(t *testing.T) {
d, pk := NewTestDirectory(t, true)
cc := NewCC(d.LatestSTR(), d.LatestSTR(), true, pk)
cc := NewCC(d.LatestSTR(), true, pk)

N := 5

Expand Down Expand Up @@ -267,7 +267,7 @@ func TestVerifyTimeSkew(t *testing.T) {

func TestVerifyMonitoring(t *testing.T) {
d, pk := NewTestDirectory(t, true)
cc := NewCC(d.LatestSTR(), d.LatestSTR(), true, pk)
cc := NewCC(d.LatestSTR(), true, pk)

N := 5

Expand Down Expand Up @@ -308,29 +308,49 @@ func TestVerifyMonitoring(t *testing.T) {
if err := monitorAndVerify(d, cc, alice, key, cc.SavedSTR.Epoch, d.LatestSTR().Epoch); err != CheckPassed {
t.Error(err)
}
// TODO: more test (prior history but after registration)
}

// Expect the ConsistencyChecks to panic:
// - If: StartEpoch < SavedEpoch + 1
func TestVerifyMonitoringBadEpoch0(t *testing.T) {
func TestVeriryPriorHistory(t *testing.T) {
d, pk := NewTestDirectory(t, true)
cc := NewCC(d.LatestSTR(), d.LatestSTR(), true, pk)
cc := NewCC(d.LatestSTR(), true, pk)

N := 5

// verify prior history
for i := 0; i < N; i++ {
d.Update()
}
if err := monitorAndVerify(d, cc, alice, nil, 0, d.LatestSTR().Epoch); err != CheckPassed {
t.Error("Unexpected verification result")
t.Error(err)
}
if err := monitorAndVerify(d, cc, alice, nil, 0, d.LatestSTR().Epoch-2); err != CheckPassed ||
cc.SavedSTR.Epoch != d.LatestSTR().Epoch {
t.Error("Expect saved epoch is", d.LatestSTR().Epoch, "got", cc.SavedSTR.Epoch)
t.Error(err)
}

defer func() {
if recover() == nil {
t.Fatal("Expect HandleResponse panic")
}
}()
if err := monitorAndVerify(d, cc, alice, nil, cc.SavedSTR.Epoch-1, d.LatestSTR().Epoch); err != CheckPassed {
// register
if _, e2 := registerAndVerify(d, cc, alice, key); e2 != CheckPassed {
t.Error("Cannot register new binding")
}
// or we can verify prior history after registering
if err := monitorAndVerify(d, cc, alice, nil, 0, d.LatestSTR().Epoch); err != CheckPassed {
t.Error(err)
}
if err := monitorAndVerify(d, cc, alice, nil, 3, d.LatestSTR().Epoch); err != CheckPassed {
t.Error(err)
}
if err := monitorAndVerify(d, cc, alice, nil, d.LatestSTR().Epoch-1, d.LatestSTR().Epoch); err != CheckPassed {
t.Error(err)
}
if err := monitorAndVerify(d, cc, alice, nil, 0, d.LatestSTR().Epoch-5); err != CheckPassed {
t.Error(err)
}

// monitor binding was inserted
d.Update()
if err := monitorAndVerify(d, cc, alice, key, cc.SavedSTR.Epoch, d.LatestSTR().Epoch); err != CheckPassed {
t.Error(err)
}
}
Expand All @@ -339,7 +359,7 @@ func TestVerifyMonitoringBadEpoch0(t *testing.T) {
// - If: StartEpoch > SavedEpoch + 1
func TestVerifyMonitoringBadEpoch1(t *testing.T) {
d, pk := NewTestDirectory(t, true)
cc := NewCC(d.LatestSTR(), d.LatestSTR(), true, pk)
cc := NewCC(d.LatestSTR(), true, pk)

N := 5

Expand All @@ -366,7 +386,7 @@ func TestVerifyMonitoringBadEpoch1(t *testing.T) {

func TestMalformedMonitoringResponse(t *testing.T) {
d, pk := NewTestDirectory(t, true)
cc := NewCC(d.LatestSTR(), d.LatestSTR(), true, pk)
cc := NewCC(d.LatestSTR(), true, pk)

// len(AP) == 0
malformedResponse := &Response{
Expand Down

0 comments on commit 0c5a61f

Please sign in to comment.