Skip to content

Commit

Permalink
Fix verifyFulfilledPromise()
Browse files Browse the repository at this point in the history
  • Loading branch information
vqhuy committed Jun 3, 2017
1 parent 67bdf0a commit 3e4dcc5
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 39 deletions.
2 changes: 1 addition & 1 deletion client/coniksclient/internal/cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func init() {
func run(cmd *cobra.Command) {
isDebugging, _ := strconv.ParseBool(cmd.Flag("debug").Value.String())
conf := loadConfigOrExit(cmd)
cc := p.NewCC(nil, conf.SigningPubKey, make(map[string]uint64), true)
cc := p.NewCC(nil, conf.SigningPubKey, make(map[string]uint64), true, nil)

state, err := terminal.MakeRaw(int(os.Stdin.Fd()))
if err != nil {
Expand Down
33 changes: 22 additions & 11 deletions protocol/consistencychecks.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ type ConsistencyChecks struct {
// Entries are kept even the binding was inserted into the directory.
RegEpoch map[string]uint64

// oldSTR stores the previous verified STR.
// This is used as a cache to verify the TB.
oldSTR *DirSTR

// extensions settings
useTBs bool
TBs map[string]*TemporaryBinding
Expand All @@ -39,19 +43,25 @@ type ConsistencyChecks struct {
// NewCC creates an instance of ConsistencyChecks using
// a CONIKS directory's pinned STR at epoch 0, or
// the consistency state read from persistent storage.
func NewCC(savedSTR *DirSTR, signKey sign.PublicKey, regs map[string]uint64, useTBs bool) *ConsistencyChecks {
func NewCC(savedSTR *DirSTR, signKey sign.PublicKey, regs map[string]uint64,
useTBs bool, tbs map[string]*TemporaryBinding) *ConsistencyChecks {
// TODO: see #110
if !useTBs {
panic("[coniks] Currently the server is forced to use TBs")
}
cc := &ConsistencyChecks{
auditorState: newAuditorState(signKey, savedSTR),
RegEpoch: regs,
Bindings: make(map[string][]byte),
RegEpoch: regs,
oldSTR: savedSTR,
useTBs: useTBs,
}
if useTBs {
cc.TBs = make(map[string]*TemporaryBinding)
if tbs == nil {
cc.TBs = make(map[string]*TemporaryBinding)
} else {
cc.TBs = tbs
}
}
return cc
}
Expand Down Expand Up @@ -287,14 +297,15 @@ func (cc *ConsistencyChecks) updateTBs(requestType int, msg *Response,
case KeyLookupType:
df := msg.DirectoryResponse.(*DirectoryProof)
ap := df.AP
str := df.STR
proofType := ap.ProofType()
switch {
case msg.Error == ReqSuccess && proofType == m.ProofOfInclusion:
if err := cc.verifyFulfilledPromise(uname, str, ap); err != nil {
return err
}
delete(cc.TBs, uname)
// FIXME: We don' support this for now,
// until we know how to cache the issued epoch. (See #116)
// case msg.Error == ReqSuccess && proofType == m.ProofOfInclusion:
// if err := cc.verifyFulfilledPromise(uname, str, ap); err != nil {
// return err
// }
// delete(cc.TBs, uname)

case msg.Error == ReqSuccess && proofType == m.ProofOfAbsence:
if err := cc.verifyReturnedPromise(df, key); err != nil {
Expand All @@ -320,9 +331,9 @@ func (cc *ConsistencyChecks) updateTBs(requestType int, msg *Response,
// in the directory as promised.
func (cc *ConsistencyChecks) verifyFulfilledPromise(uname string, str *DirSTR,
ap *m.AuthenticationPath) error {
// FIXME: Which epoch did this lookup happen in?
if tb, ok := cc.TBs[uname]; ok {
if !bytes.Equal(ap.LookupIndex, tb.Index) ||
if cc.oldSTR.Epoch+1 != str.Epoch ||
!bytes.Equal(ap.LookupIndex, tb.Index) ||
!bytes.Equal(ap.Leaf.Value, tb.Value) {
return CheckBrokenPromise
}
Expand Down
61 changes: 34 additions & 27 deletions protocol/consistencychecks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"testing"

"github.com/coniks-sys/coniks-go/crypto/sign"
"github.com/coniks-sys/coniks-go/merkletree"
)

Expand Down Expand Up @@ -33,14 +34,18 @@ func lookupAndVerify(d *ConiksDirectory, cc *ConsistencyChecks,
}

func monitorAndVerify(d *ConiksDirectory, cc *ConsistencyChecks,
name string, key []byte, startEp, endEp uint64) error {
name string, key []byte, startEp, endEp uint64) (error, error) {
request := &MonitoringRequest{
Username: name,
StartEpoch: startEp,
EndEpoch: endEp,
}
res, _ := d.Monitor(request)
return cc.HandleResponse(MonitoringType, res, name, key)
res, err := d.Monitor(request)
return err, cc.HandleResponse(MonitoringType, res, name, key)
}

func newTestVerifier(str *DirSTR, pk sign.PublicKey) *ConsistencyChecks {
return NewCC(str, pk, make(map[string]uint64), true, nil)
}

func TestVerifyWithError(t *testing.T) {
Expand All @@ -53,7 +58,7 @@ func TestVerifyWithError(t *testing.T) {
str2.Signature[0]++
str.SignedTreeRoot = &str2

cc := NewCC(str, pk, make(map[string]uint64), true)
cc := newTestVerifier(str, pk)

e1, e2 := registerAndVerify(d, cc, alice, key)
if e1 != ReqSuccess {
Expand All @@ -66,7 +71,7 @@ func TestVerifyWithError(t *testing.T) {

func TestMalformedClientMessage(t *testing.T) {
d, pk := NewTestDirectory(t, true)
cc := NewCC(d.LatestSTR(), pk, make(map[string]uint64), true)
cc := newTestVerifier(d.LatestSTR(), pk)

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

func TestMalformedDirectoryMessage(t *testing.T) {
d, pk := NewTestDirectory(t, true)
cc := NewCC(d.LatestSTR(), pk, make(map[string]uint64), true)
cc := newTestVerifier(d.LatestSTR(), pk)

request := &RegistrationRequest{
Username: "alice",
Expand All @@ -96,8 +101,7 @@ func TestMalformedDirectoryMessage(t *testing.T) {

func TestVerifyRegistrationResponseWithTB(t *testing.T) {
d, pk := NewTestDirectory(t, true)

cc := NewCC(d.LatestSTR(), pk, make(map[string]uint64), true)
cc := newTestVerifier(d.LatestSTR(), pk)

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

func TestVerifyFullfilledPromise(t *testing.T) {
d, pk := NewTestDirectory(t, true)

cc := NewCC(d.LatestSTR(), pk, make(map[string]uint64), true)
cc := newTestVerifier(d.LatestSTR(), pk)

if e1, e2 := registerAndVerify(d, cc, alice, key); e1 != ReqSuccess || e2 != CheckPassed {
t.Error(e1)
Expand All @@ -156,21 +159,21 @@ func TestVerifyFullfilledPromise(t *testing.T) {
t.Fatal("Expect the directory to return signed promises")
}

clientLastEpoch := cc.SavedSTR.Epoch + 1

d.Update()

for i := 0; i < 2; i++ {
if e1, e2 := lookupAndVerify(d, cc, alice, key); e1 != ReqSuccess || e2 != CheckPassed {
t.Error(e1)
t.Error(e2)
}
if e1, e2 := monitorAndVerify(d, cc, alice, key, clientLastEpoch, d.LatestSTR().Epoch); e1 != ReqSuccess || e2 != CheckPassed {
t.Error(e1)
t.Error(e2)
}

// should contain the TBs of bob
if len(cc.TBs) != 1 || cc.TBs[bob] == nil {
t.Error("Expect the directory to insert the binding as promised")
}

if e1, e2 := lookupAndVerify(d, cc, bob, key); e1 != ReqSuccess || e2 != CheckPassed {
if e1, e2 := monitorAndVerify(d, cc, bob, key, clientLastEpoch, d.LatestSTR().Epoch); e1 != ReqSuccess || e2 != CheckPassed {
t.Error(e1)
t.Error(e2)
}
Expand All @@ -181,8 +184,7 @@ func TestVerifyFullfilledPromise(t *testing.T) {

func TestVerifyKeyLookupResponseWithTB(t *testing.T) {
d, pk := NewTestDirectory(t, true)

cc := NewCC(d.LatestSTR(), pk, make(map[string]uint64), true)
cc := newTestVerifier(d.LatestSTR(), pk)

// do lookup first
if e1, e2 := lookupAndVerify(d, cc, alice, key); e1 != ReqNameNotFound || e2 != CheckPassed {
Expand Down Expand Up @@ -242,20 +244,23 @@ func TestVerifyKeyLookupResponseWithTB(t *testing.T) {
func TestVerifyMonitoring(t *testing.T) {
N := 5
d, pk := NewTestDirectory(t, true)
cc := NewCC(d.LatestSTR(), pk, make(map[string]uint64), true)
cc := newTestVerifier(d.LatestSTR(), pk)

registerAndVerify(d, cc, alice, key)

// monitor binding was inserted
d.Update()

if err := monitorAndVerify(d, cc, alice, key, cc.SavedSTR.Epoch+1, d.LatestSTR().Epoch); err != CheckPassed {
t.Error(err)
if e1, e2 := monitorAndVerify(d, cc, alice, key, cc.SavedSTR.Epoch+1, d.LatestSTR().Epoch); e1 != ReqSuccess || e2 != CheckPassed {
t.Error(e1)
t.Error(e2)
}
for i := 0; i < N; i++ {
d.Update()
}
if err := monitorAndVerify(d, cc, alice, key, cc.SavedSTR.Epoch+1, d.LatestSTR().Epoch); err != CheckPassed {
t.Error(err)
if e1, e2 := monitorAndVerify(d, cc, alice, key, cc.SavedSTR.Epoch+1, d.LatestSTR().Epoch); e1 != ReqSuccess || e2 != CheckPassed {
t.Error(e1)
t.Error(e2)
}
}

Expand All @@ -264,21 +269,23 @@ func TestVerifyMonitoring(t *testing.T) {
func TestVerifyMonitoringBadEpoch(t *testing.T) {
N := 5
d, pk := NewTestDirectory(t, true)
cc := NewCC(d.LatestSTR(), pk, make(map[string]uint64), true)
cc := newTestVerifier(d.LatestSTR(), pk)

registerAndVerify(d, cc, alice, key)

for i := 0; i < N; i++ {
d.Update()
}

if err := monitorAndVerify(d, cc, alice, nil, cc.SavedSTR.Epoch+2, d.LatestSTR().Epoch); err != CheckUnexpectedMonitoringEpoch {
t.Error(err)
if e1, e2 := monitorAndVerify(d, cc, alice, nil, cc.SavedSTR.Epoch+2, d.LatestSTR().Epoch); e1 != ReqSuccess || e2 != CheckUnexpectedMonitoringEpoch {
t.Error(e1)
t.Error(e2)
}
}

func TestMalformedMonitoringResponse(t *testing.T) {
d, pk := NewTestDirectory(t, true)
cc := NewCC(d.LatestSTR(), pk, make(map[string]uint64), true)
cc := newTestVerifier(d.LatestSTR(), pk)

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

0 comments on commit 3e4dcc5

Please sign in to comment.