Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge DirectoryProof and DirectoryProofs into one #179

Merged
merged 1 commit into from
Jul 20, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 1 addition & 12 deletions client/encoding.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand All @@ -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")
}
Expand Down
2 changes: 1 addition & 1 deletion client/encoding_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
Expand Down
10 changes: 5 additions & 5 deletions keyserver/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
10 changes: 1 addition & 9 deletions keyserver/testutil/testutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}

Expand Down
30 changes: 15 additions & 15 deletions protocol/consistencychecks.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
Expand All @@ -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
Expand Down Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down Expand Up @@ -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
}
Expand All @@ -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:
Expand Down Expand Up @@ -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 {
Expand Down
18 changes: 9 additions & 9 deletions protocol/directory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down Expand Up @@ -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")) {
Expand All @@ -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 {
Expand All @@ -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)
}
Expand All @@ -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)
}
Expand All @@ -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)
}
Expand All @@ -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)
}
Expand Down
60 changes: 16 additions & 44 deletions protocol/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
Expand All @@ -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),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should update the documentation to specify that the length of AP and STR is expected to be equal to 1. Same goes for NewKeyLookupProof below.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

TB: tb,
},
}, e
Expand All @@ -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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why keep them as arrays then?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is only the case for registrations and key lookups. Monitoring and LookupInEpochs return more than one auth path and/or STR. And even registrations are going to return multiple auth paths and STRs when we implement prior history verification.

// 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.
Expand All @@ -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
Expand All @@ -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,
},
Expand All @@ -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,
},
Expand Down Expand Up @@ -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
Expand All @@ -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
}