From 9d5f9fd1fb65ebebbb83e5c40a54209caf2bddf2 Mon Sep 17 00:00:00 2001 From: huyvq Date: Mon, 5 Jun 2017 21:36:13 +0700 Subject: [PATCH] Merge `DirectoryProof` and `DirectoryProofs` into one --- client/encoding.go | 13 +------- client/encoding_test.go | 2 +- keyserver/server_test.go | 10 +++--- keyserver/testutil/testutil.go | 10 +----- protocol/consistencychecks.go | 30 ++++++++--------- protocol/directory_test.go | 18 +++++----- protocol/message.go | 60 +++++++++------------------------- 7 files changed, 48 insertions(+), 95 deletions(-) diff --git a/client/encoding.go b/client/encoding.go index ab2a5c8..231cc24 100644 --- a/client/encoding.go +++ b/client/encoding.go @@ -35,7 +35,7 @@ func UnmarshalResponse(t int, msg []byte) *p.Response { } switch t { - case p.RegistrationType, p.KeyLookupType: + case p.RegistrationType, p.KeyLookupType, p.KeyLookupInEpochType, p.MonitoringType: response := new(p.DirectoryProof) if err := json.Unmarshal(res.DirectoryResponse, &response); err != nil { return &p.Response{ @@ -46,17 +46,6 @@ func UnmarshalResponse(t int, msg []byte) *p.Response { Error: res.Error, DirectoryResponse: response, } - case p.KeyLookupInEpochType, p.MonitoringType: - response := new(p.DirectoryProofs) - if err := json.Unmarshal(res.DirectoryResponse, &response); err != nil { - return &p.Response{ - Error: p.ErrMalformedDirectoryMessage, - } - } - return &p.Response{ - Error: res.Error, - DirectoryResponse: response, - } default: panic("Unknown request type") } diff --git a/client/encoding_test.go b/client/encoding_test.go index 4abc9c7..e7812ec 100644 --- a/client/encoding_test.go +++ b/client/encoding_test.go @@ -42,7 +42,7 @@ func TestUnmarshalSampleMessage(t *testing.T) { Key: []byte("key")}) msg, _ := keyserver.MarshalResponse(res) response := UnmarshalResponse(protocol.RegistrationType, []byte(msg)) - str := response.DirectoryResponse.(*protocol.DirectoryProof).STR + str := response.DirectoryResponse.(*protocol.DirectoryProof).STR[0] if !bytes.Equal(d.LatestSTR().Serialize(), str.Serialize()) { t.Error("Cannot unmarshal Associate Data properly") } diff --git a/keyserver/server_test.go b/keyserver/server_test.go index 9d202f4..6374041 100644 --- a/keyserver/server_test.go +++ b/keyserver/server_test.go @@ -334,7 +334,7 @@ func TestRegisterAndLookupInTheSameEpoch(t *testing.T) { } var str testutil.ExpectingSTR - err = json.Unmarshal(response.DirectoryResponse.STR, &str) + err = json.Unmarshal(response.DirectoryResponse.STR[0], &str) if err != nil { t.Fatal(err) } @@ -377,7 +377,7 @@ func TestRegisterAndLookup(t *testing.T) { } var str testutil.ExpectingSTR - err = json.Unmarshal(res.DirectoryResponse.STR, &str) + err = json.Unmarshal(res.DirectoryResponse.STR[0], &str) if err != nil { t.Fatal(err) } @@ -420,7 +420,7 @@ func TestKeyLookup(t *testing.T) { } var str testutil.ExpectingSTR - err = json.Unmarshal(response.DirectoryResponse.STR, &str) + err = json.Unmarshal(response.DirectoryResponse.STR[0], &str) if err != nil { t.Fatal(err) } @@ -461,7 +461,7 @@ func TestKeyLookupInEpoch(t *testing.T) { t.Fatal(err) } - var response testutil.ExpectingDirProofsResponse + var response testutil.ExpectingDirProofResponse err = json.Unmarshal(rev, &response) if err != nil { t.Fatal(err) @@ -508,7 +508,7 @@ func TestMonitoring(t *testing.T) { t.Fatal(err) } - var response testutil.ExpectingDirProofsResponse + var response testutil.ExpectingDirProofResponse err = json.Unmarshal(rev, &response) if err != nil { t.Fatal(err) diff --git a/keyserver/testutil/testutil.go b/keyserver/testutil/testutil.go index 5958141..199c9c9 100644 --- a/keyserver/testutil/testutil.go +++ b/keyserver/testutil/testutil.go @@ -42,19 +42,11 @@ const ( ) type ExpectingDirProofResponse struct { - Error protocol.ErrorCode - DirectoryResponse struct { - AP json.RawMessage - STR json.RawMessage - TB json.RawMessage - } -} - -type ExpectingDirProofsResponse struct { Error protocol.ErrorCode DirectoryResponse struct { AP []json.RawMessage STR []json.RawMessage + TB json.RawMessage } } diff --git a/protocol/consistencychecks.go b/protocol/consistencychecks.go index 87d6141..bc181a9 100644 --- a/protocol/consistencychecks.go +++ b/protocol/consistencychecks.go @@ -76,14 +76,10 @@ func (cc *ConsistencyChecks) HandleResponse(requestType int, msg *Response, return err.(ErrorCode) } switch requestType { - case RegistrationType, KeyLookupType: + case RegistrationType, KeyLookupType, KeyLookupInEpochType, MonitoringType: if _, ok := msg.DirectoryResponse.(*DirectoryProof); !ok { return ErrMalformedDirectoryMessage } - case MonitoringType, KeyLookupInEpochType: - if _, ok := msg.DirectoryResponse.(*DirectoryProofs); !ok { - return ErrMalformedDirectoryMessage - } default: panic("[coniks] Unknown request type") } @@ -105,7 +101,7 @@ func (cc *ConsistencyChecks) updateSTR(requestType int, msg *Response) error { var str *DirSTR switch requestType { case RegistrationType, KeyLookupType: - str = msg.DirectoryResponse.(*DirectoryProof).STR + str = msg.DirectoryResponse.(*DirectoryProof).STR[0] // First response if cc.SavedSTR == nil { cc.SavedSTR = str @@ -177,8 +173,10 @@ func (cc *ConsistencyChecks) checkConsistency(requestType int, msg *Response, func (cc *ConsistencyChecks) verifyRegistration(msg *Response, uname string, key []byte) error { df := msg.DirectoryResponse.(*DirectoryProof) - ap := df.AP - str := df.STR + // FIXME: should explicitly validate that + // len(df.AP) == len(df.STR) == 1 + ap := df.AP[0] + str := df.STR[0] proofType := ap.ProofType() switch { @@ -199,8 +197,10 @@ func (cc *ConsistencyChecks) verifyRegistration(msg *Response, func (cc *ConsistencyChecks) verifyKeyLookup(msg *Response, uname string, key []byte) error { df := msg.DirectoryResponse.(*DirectoryProof) - ap := df.AP - str := df.STR + // FIXME: should explicitly validate that + // len(df.AP) == len(df.STR) == 1 + ap := df.AP[0] + str := df.STR[0] proofType := ap.ProofType() switch { @@ -256,7 +256,7 @@ func (cc *ConsistencyChecks) updateTBs(requestType int, msg *Response, switch requestType { case RegistrationType: df := msg.DirectoryResponse.(*DirectoryProof) - if df.AP.ProofType() == m.ProofOfAbsence { + if df.AP[0].ProofType() == m.ProofOfAbsence { if err := cc.verifyReturnedPromise(df, key); err != nil { return err } @@ -266,8 +266,8 @@ func (cc *ConsistencyChecks) updateTBs(requestType int, msg *Response, case KeyLookupType: df := msg.DirectoryResponse.(*DirectoryProof) - ap := df.AP - str := df.STR + ap := df.AP[0] + str := df.STR[0] proofType := ap.ProofType() switch { case msg.Error == ReqSuccess && proofType == m.ProofOfInclusion: @@ -315,8 +315,8 @@ func (cc *ConsistencyChecks) verifyFulfilledPromise(uname string, str *DirSTR, // These above checks should be performed before calling this method. func (cc *ConsistencyChecks) verifyReturnedPromise(df *DirectoryProof, key []byte) error { - ap := df.AP - str := df.STR + ap := df.AP[0] + str := df.STR[0] tb := df.TB if tb == nil { diff --git a/protocol/directory_test.go b/protocol/directory_test.go index 2571ca9..05f098d 100644 --- a/protocol/directory_test.go +++ b/protocol/directory_test.go @@ -17,7 +17,7 @@ func TestRegisterWithTB(t *testing.T) { if err != ReqSuccess { t.Fatal("Unable to register") } - if ap := df.AP; ap == nil || bytes.Equal(ap.LookupIndex, ap.Leaf.Index) { + if ap := df.AP[0]; ap == nil || bytes.Equal(ap.LookupIndex, ap.Leaf.Index) { t.Fatal("Expect a proof of absence") } if df.TB == nil { @@ -51,7 +51,7 @@ func TestRegisterExistedUserWithTB(t *testing.T) { if err != ReqNameExisted { t.Fatal("Expect error code", ReqNameExisted, "got", err) } - if ap := df.AP; ap == nil || bytes.Equal(ap.LookupIndex, ap.Leaf.Index) { + if ap := df.AP[0]; ap == nil || bytes.Equal(ap.LookupIndex, ap.Leaf.Index) { t.Fatal("Expect a proof of absence") } if df.TB == nil { @@ -69,7 +69,7 @@ func TestRegisterExistedUserWithTB(t *testing.T) { if err != ReqNameExisted { t.Fatal("Expect error code", ReqNameExisted, "got", err) } - if ap := df.AP; ap == nil || !bytes.Equal(ap.LookupIndex, ap.Leaf.Index) { + if ap := df.AP[0]; ap == nil || !bytes.Equal(ap.LookupIndex, ap.Leaf.Index) { t.Fatal("Expect a proof of inclusion") } if df.TB != nil { @@ -101,7 +101,7 @@ func TestKeyLookupWithTB(t *testing.T) { if res.Error != ReqSuccess { t.Fatal("Expect no error", "got", res.Error) } - if ap := df.AP; ap == nil || bytes.Equal(ap.LookupIndex, ap.Leaf.Index) { + if ap := df.AP[0]; ap == nil || bytes.Equal(ap.LookupIndex, ap.Leaf.Index) { t.Fatal("Expect a proof of absence") } if df.TB == nil || !bytes.Equal(df.TB.Value, []byte("key")) { @@ -119,7 +119,7 @@ func TestKeyLookupWithTB(t *testing.T) { // expect a proof of inclusion res, _ = d.KeyLookup(&KeyLookupRequest{Username: "alice"}) df = res.DirectoryResponse.(*DirectoryProof) - if ap := df.AP; ap == nil || !bytes.Equal(ap.LookupIndex, ap.Leaf.Index) { + if ap := df.AP[0]; ap == nil || !bytes.Equal(ap.LookupIndex, ap.Leaf.Index) { t.Fatal("Expect a proof of inclusion") } if df.TB != nil { @@ -143,7 +143,7 @@ func TestDirectoryMonitoring(t *testing.T) { // missed from epoch 2 res, err := d.Monitor(&MonitoringRequest{"alice", uint64(2), d.LatestSTR().Epoch}) - df := res.DirectoryResponse.(*DirectoryProofs) + df := res.DirectoryResponse.(*DirectoryProof) if err != ReqSuccess { t.Fatal("Unable to perform key lookup in epoch", 2) } @@ -164,7 +164,7 @@ func TestDirectoryMonitoring(t *testing.T) { // assert the number of STRs returned is correct res, err = d.Monitor(&MonitoringRequest{"alice", uint64(2), d.LatestSTR().Epoch + 5}) - df = res.DirectoryResponse.(*DirectoryProofs) + df = res.DirectoryResponse.(*DirectoryProof) if err != ReqSuccess { t.Fatal("Unable to perform key lookup in epoch", 2) } @@ -183,7 +183,7 @@ func TestDirectoryKeyLookupInEpoch(t *testing.T) { // lookup at epoch 1, expect a proof of absence & ReqNameNotFound res, err := d.KeyLookupInEpoch(&KeyLookupInEpochRequest{"alice", uint64(1)}) - df := res.DirectoryResponse.(*DirectoryProofs) + df := res.DirectoryResponse.(*DirectoryProof) if err != ReqNameNotFound { t.Fatal("Expect error", ReqNameNotFound, "got", err) } @@ -202,7 +202,7 @@ func TestDirectoryKeyLookupInEpoch(t *testing.T) { } res, err = d.KeyLookupInEpoch(&KeyLookupInEpochRequest{"alice", uint64(5)}) - df = res.DirectoryResponse.(*DirectoryProofs) + df = res.DirectoryResponse.(*DirectoryProof) if err != ReqSuccess { t.Fatal("Expect error", ReqSuccess, "got", err) } diff --git a/protocol/message.go b/protocol/message.go index bd3d58c..e8e3d55 100644 --- a/protocol/message.go +++ b/protocol/message.go @@ -121,25 +121,14 @@ type Response struct { // to a CONIKS client. type DirectoryResponse interface{} -// A DirectoryProof response includes an authentication path AP for a -// given username-to-key binding in the directory, a signed tree root -// STR, and optionally a temporary binding for the given binding for a -// single epoch. A CONIKS directory returns this DirectoryResponse -// type upon a RegistrationRequest or a KeyLookupRequest. -type DirectoryProof struct { - AP *m.AuthenticationPath - STR *DirSTR - TB *TemporaryBinding `json:",omitempty"` -} - -// A DirectoryProofs response includes a list of authentication paths +// A DirectoryProof response includes a list of authentication paths // AP for a given username-to-key binding in the directory and a list of -// signed tree roots STR for a range of epochs. A CONIKS directory returns -// this DirectoryResponse type upon a KeyLookupInEpochRequest or a -// MonitoringRequest. -type DirectoryProofs struct { +// signed tree roots STR for a range of epochs, and optionally +// a temporary binding for the given binding for a single epoch. +type DirectoryProof struct { AP []*m.AuthenticationPath STR []*DirSTR + TB *TemporaryBinding `json:",omitempty"` } // An STRHistoryRange response includes a list of signed tree roots @@ -159,12 +148,12 @@ func NewErrorResponse(e ErrorCode) *Response { } var _ DirectoryResponse = (*DirectoryProof)(nil) -var _ DirectoryResponse = (*DirectoryProofs)(nil) var _ DirectoryResponse = (*STRHistoryRange)(nil) // NewRegistrationProof creates the response message a CONIKS directory // sends to a client upon a RegistrationRequest, // and returns a Response containing a DirectoryProof struct. +// The length of `AP` and `STR` must to be equal to 1. // directory.Register() passes an authentication path ap, temporary binding // tb and error code e according to the result of the registration, and // the signed tree root for the latest epoch str. @@ -176,8 +165,8 @@ func NewRegistrationProof(ap *m.AuthenticationPath, str *DirSTR, return &Response{ Error: e, DirectoryResponse: &DirectoryProof{ - AP: ap, - STR: str, + AP: append([]*m.AuthenticationPath{}, ap), + STR: append([]*DirSTR{}, str), TB: tb, }, }, e @@ -186,6 +175,7 @@ func NewRegistrationProof(ap *m.AuthenticationPath, str *DirSTR, // NewKeyLookupProof creates the response message a CONIKS directory // sends to a client upon a KeyLookupRequest, // and returns a Response containing a DirectoryProof struct. +// The length of `AP` and `STR` must to be equal to 1. // directory.KeyLookup() passes an authentication path ap, temporary binding // tb and error code e according to the result of the key lookup, and the // signed tree root for the latest epoch str. @@ -197,8 +187,8 @@ func NewKeyLookupProof(ap *m.AuthenticationPath, str *DirSTR, return &Response{ Error: e, DirectoryResponse: &DirectoryProof{ - AP: ap, - STR: str, + AP: append([]*m.AuthenticationPath{}, ap), + STR: append([]*DirSTR{}, str), TB: tb, }, }, e @@ -218,7 +208,7 @@ func NewKeyLookupInEpochProof(ap *m.AuthenticationPath, aps := append([]*m.AuthenticationPath{}, ap) return &Response{ Error: e, - DirectoryResponse: &DirectoryProofs{ + DirectoryResponse: &DirectoryProof{ AP: aps, STR: str, }, @@ -237,7 +227,7 @@ func NewMonitoringProof(ap []*m.AuthenticationPath, str []*DirSTR) (*Response, ErrorCode) { return &Response{ Error: ReqSuccess, - DirectoryResponse: &DirectoryProofs{ + DirectoryResponse: &DirectoryProof{ AP: ap, STR: str, }, @@ -267,13 +257,10 @@ func (msg *Response) validate() error { } switch df := msg.DirectoryResponse.(type) { case *DirectoryProof: - if df.AP == nil || df.STR == nil { + if len(df.STR) == 0 || len(df.AP) == 0 { return ErrMalformedDirectoryMessage } return nil - case *DirectoryProofs: - // TODO: also do above assertions here - return nil case *STRHistoryRange: // treat the STRHistoryRange as an auditor response // bc validate is only called by a client @@ -296,22 +283,7 @@ func (msg *Response) validate() error { // If the response contains a range of authentication paths, // the key is obtained from the authentication path corresponding // to the most recent signed tree root. +// FIXME: remove this obsolete function func (msg *Response) GetKey() ([]byte, error) { - if err := msg.validate(); err != nil { - return nil, err - } - switch df := msg.DirectoryResponse.(type) { - case *DirectoryProof: - if df.AP.ProofType() == m.ProofOfAbsence { - if df.TB != nil { // FIXME: this check could be eliminated when we force to use TB? - return df.TB.Value, nil - } - return nil, nil - } - return df.AP.Leaf.Value, nil - case *DirectoryProofs: - return df.AP[len(df.AP)-1].Leaf.Value, nil - default: - panic("[coniks] Malformed response") - } + return nil, nil }