Skip to content

Commit

Permalink
Changes:
Browse files Browse the repository at this point in the history
1. SignedEntry.Signatures now in the same order as
SignedEntry.Entry.Edges

WIP:
    Handshakes
  • Loading branch information
ayuryshev committed Apr 3, 2019
1 parent 810c2e1 commit 6eb91fe
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 18 deletions.
3 changes: 2 additions & 1 deletion pkg/transport-discovery/client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,8 @@ func TestRegisterTransportResponses(t *testing.T) {
}

func TestRegisterTransports(t *testing.T) {
sEntry := &transport.SignedEntry{Entry: newTestEntry(), Signatures: [2]cipher.Sig{}}
// Signatures does not matter in this test
sEntry := &transport.SignedEntry{Entry: newTestEntry()}

srv := httptest.NewServer(authHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "/transports/", r.URL.String())
Expand Down
5 changes: 3 additions & 2 deletions pkg/transport/discovery_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ import (
func ExampleNewDiscoveryMock() {
dc := NewDiscoveryMock()
pk1, _ := cipher.GenerateKeyPair()
pk2, sk2 := cipher.GenerateKeyPair()
pk2, _ := cipher.GenerateKeyPair()
entry := &Entry{Type: "mock", EdgesKeys: SortPubKeys(pk1, pk2)}
sEntry := &SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{entry.Signature(sk2)}}

sEntry := &SignedEntry{Entry: entry}

if Ok := dc.RegisterTransports(context.TODO(), sEntry); Ok == nil {
fmt.Println("RegisterTransport success")
Expand Down
26 changes: 26 additions & 0 deletions pkg/transport/entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,32 @@ type SignedEntry struct {
Registered int64 `json:"registered,omitempty"`
}

func (se *SignedEntry) Index(pk cipher.PubKey) byte {
if pk == se.Entry.Edges()[1] {
return 1
}
return 0
}

// SetSignature sets Signature for a given PubKey in correct position
func (se *SignedEntry) SetSignature(pk cipher.PubKey, secKey cipher.SecKey) {
idx := se.Index(pk)
se.Signatures[idx] = se.Entry.Signature(secKey)
}

// GetSignature gets Signature for a given PubKey from correct position
func (se *SignedEntry) GetSignature(pk cipher.PubKey) cipher.Sig {
idx := se.Index(pk)
return se.Signatures[idx]
}

// NewSignedEntry creates a SignedEntry with first signature
func NewSignedEntry(entry *Entry, pk cipher.PubKey, secKey cipher.SecKey) *SignedEntry {
se := &SignedEntry{Entry: entry}
se.SetSignature(pk, secKey)
return se
}

// Status represents the current state of a Transport from the perspective
// from a Transport's single edge. Each Transport will have two perspectives;
// one from each of it's edges.
Expand Down
48 changes: 48 additions & 0 deletions pkg/transport/entry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"

"github.com/google/uuid"

"github.com/skycoin/skywire/pkg/cipher"
)

Expand Down Expand Up @@ -79,3 +80,50 @@ func ExampleEntry_SetEdges() {
// entryAB.ID != uuid.UUID{}
// entryAB.ID == entryBA.ID
}

func ExampleSignedEntry_SetSignature() {
pkA, skA := cipher.GenerateKeyPair()
pkB, skB := cipher.GenerateKeyPair()

entry := NewEntry(pkA, pkB, "mock", true)
sEntry := &SignedEntry{Entry: entry}

if sEntry.Signatures[0].Null() && sEntry.Signatures[1].Null() {
fmt.Println("No signatures set")
}

sEntry.SetSignature(pkA, skA)
if (!sEntry.Signatures[0].Null() && sEntry.Signatures[1].Null()) ||
(!sEntry.Signatures[1].Null() && sEntry.Signatures[0].Null()) {
fmt.Println("One signature set")
}

sEntry.SetSignature(pkB, skB)
if !sEntry.Signatures[0].Null() && !sEntry.Signatures[1].Null() {
fmt.Println("Both signatures set")
}

// Output: No signatures set
// One signature set
// Both signatures set
}

func ExampleSignedEntry_GetSignature() {
pkA, skA := cipher.GenerateKeyPair()
pkB, skB := cipher.GenerateKeyPair()

entry := NewEntry(pkA, pkB, "mock", true)
sEntry := &SignedEntry{Entry: entry}
sEntry.SetSignature(pkA, skA)
sEntry.SetSignature(pkB, skB)

if sEntry.GetSignature(pkA) == sEntry.Signatures[sEntry.Index(pkA)] {
fmt.Println("SignatureA got")
}
if sEntry.GetSignature(pkB) == sEntry.Signatures[sEntry.Index(pkB)] {
fmt.Println("SignatureB got")
}

// Output: SignatureA got
// SignatureB got
}
21 changes: 14 additions & 7 deletions pkg/transport/handshake.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ func settlementInitiatorHandshake(id uuid.UUID, public bool) settlementHandshake
entry.ID = GetTransportUUID(entry.Edges()[0], entry.Edges()[1], entry.Type)
}

sEntry := &SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{entry.Signature(tm.config.SecKey)}}
// sEntry := &SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{entry.Signature(tm.config.SecKey)}}

sEntry := NewSignedEntry(entry, tm.config.PubKey, tm.config.SecKey)
if err := json.NewEncoder(tr).Encode(sEntry); err != nil {
return nil, fmt.Errorf("write: %s", err)
}
Expand All @@ -53,7 +55,8 @@ func settlementInitiatorHandshake(id uuid.UUID, public bool) settlementHandshake
return nil, fmt.Errorf("read: %s", err)
}

if err := verifySig(sEntry, 1, tm.Remote(tr.Edges())); err != nil {
// Verifying remote signature
if err := verifySig(sEntry, tm.Remote(tr.Edges())); err != nil {
return nil, err
}

Expand All @@ -71,11 +74,14 @@ func settlementResponderHandshake(tm *Manager, tr Transport) (*Entry, error) {
return nil, fmt.Errorf("read: %s", err)
}

// it must be tm.Local() ?
if err := validateEntry(sEntry, tr, tm.Remote(tr.Edges())); err != nil {
return nil, err
}

sEntry.Signatures[1] = sEntry.Entry.Signature(tm.config.SecKey)
// Write second signature
// sEntry.Signatures[1] = sEntry.Entry.Signature(tm.config.SecKey)
sEntry.SetSignature(tm.Local(), tm.config.SecKey)

newEntry := tm.walkEntries(func(e *Entry) bool { return *e == *sEntry.Entry }) == nil

Expand Down Expand Up @@ -113,13 +119,14 @@ func validateEntry(sEntry *SignedEntry, tr Transport, rpk cipher.PubKey) error {
return errors.New("invalid entry edges")
}

if sEntry.Signatures[0].Null() {
// Weak check here
if sEntry.Signatures[0].Null() && sEntry.Signatures[1].Null() {
return errors.New("invalid entry signature")
}

return verifySig(sEntry, 0, rpk)
return verifySig(sEntry, rpk)
}

func verifySig(sEntry *SignedEntry, idx int, pk cipher.PubKey) error {
return cipher.VerifyPubKeySignedPayload(pk, sEntry.Signatures[idx], sEntry.Entry.ToBinary())
func verifySig(sEntry *SignedEntry, pk cipher.PubKey) error {
return cipher.VerifyPubKeySignedPayload(pk, sEntry.GetSignature(pk), sEntry.Entry.ToBinary())
}
31 changes: 24 additions & 7 deletions pkg/transport/handshake_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,23 @@ func ExampleNewHsMock() {
}

func Example_validateEntry() {
pk1, _ := cipher.GenerateKeyPair()
pk1, sk1 := cipher.GenerateKeyPair()
pk2, _ := cipher.GenerateKeyPair()
pk3, _ := cipher.GenerateKeyPair()
tr := NewMockTransport(nil, pk1, pk2)

entry := Entry{Type: "mock", EdgesKeys: SortPubKeys(pk2, pk3)}
if err := validateEntry(&SignedEntry{Entry: &entry}, tr, pk1); err != nil {
fmt.Printf(err.Error())
entryInvalidEdges := &SignedEntry{
Entry: &Entry{Type: "mock",
EdgesKeys: SortPubKeys(pk2, pk3),
}}
if err := validateEntry(entryInvalidEdges, tr, pk1); err != nil {
fmt.Println(err.Error())
}

entry := NewEntry(pk1, pk2, "mock", true)
sEntry := NewSignedEntry(entry, pk1, sk1)
if Ok := validateEntry(sEntry, tr, pk1); Ok != nil {
fmt.Printf(Ok.Error())
}

// Output: invalid entry edges
Expand Down Expand Up @@ -131,7 +140,12 @@ func TestValidateEntry(t *testing.T) {
"invalid entry signature",
},
{
&SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{entry.Signature(sk1)}},
func() *SignedEntry {
sEntry := &SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{}}
sEntry.SetSignature(pk1, sk2)
sEntry.SetSignature(pk2, sk1)
return sEntry
}(),
"Recovered pubkey does not match pubkey",
},
}
Expand All @@ -144,8 +158,11 @@ func TestValidateEntry(t *testing.T) {
})
}

sEntry := &SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{entry.Signature(sk2)}}
require.NoError(t, validateEntry(sEntry, tr, pk2))
sEntry := &SignedEntry{Entry: entry, Signatures: [2]cipher.Sig{}}
sEntry.SetSignature(pk1, sk1)
sEntry.SetSignature(pk2, sk2)

require.NoError(t, validateEntry(sEntry, tr, pk1))
}

func TestSettlementHandshake(t *testing.T) {
Expand Down
5 changes: 5 additions & 0 deletions pkg/transport/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,11 @@ func SortPubKeys(keyA, keyB cipher.PubKey) [2]cipher.PubKey {
return [2]cipher.PubKey{keyA, keyB}
}

// SortEdges sorts edges so that list-significant comes firs
func SortEdges(edges [2]cipher.PubKey) [2]cipher.PubKey {
return SortPubKeys(edges[0], edges[1])
}

// CreateTransport begins to attempt to establish transports to the given 'remote' node.
func (tm *Manager) CreateTransport(ctx context.Context, remote cipher.PubKey, tpType string, public bool) (*ManagedTransport, error) {
return tm.createTransport(ctx, remote, tpType, GetTransportUUID(tm.config.PubKey, remote, tpType), public)
Expand Down
2 changes: 1 addition & 1 deletion pkg/transport/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func (m *MockTransport) Close() error {

// Edges returns edges of MockTransport
func (m *MockTransport) Edges() [2]cipher.PubKey {
return m.edges
return SortEdges(m.edges)
}

// // Local returns the local static public key
Expand Down

0 comments on commit 6eb91fe

Please sign in to comment.