github.com/shyftnetwork/go-empyrean@v1.8.3-0.20191127201940-fbfca9338f04/swarm/pss/handshake_test.go (about)

     1  // Copyright 2018 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  // +build foo
    18  
    19  package pss
    20  
    21  import (
    22  	"strconv"
    23  	"strings"
    24  	"testing"
    25  	"time"
    26  
    27  	"github.com/ShyftNetwork/go-empyrean/swarm/log"
    28  )
    29  
    30  // asymmetrical key exchange between two directly connected peers
    31  // full address, partial address (8 bytes) and empty address
    32  func TestHandshake(t *testing.T) {
    33  	t.Skip("handshakes are not adapted to current pss core code")
    34  	t.Run("32", testHandshake)
    35  	t.Run("8", testHandshake)
    36  	t.Run("0", testHandshake)
    37  }
    38  
    39  func testHandshake(t *testing.T) {
    40  
    41  	// how much of the address we will use
    42  	useHandshake = true
    43  	var addrsize int64
    44  	var err error
    45  	addrsizestring := strings.Split(t.Name(), "/")
    46  	addrsize, _ = strconv.ParseInt(addrsizestring[1], 10, 0)
    47  
    48  	// set up two nodes directly connected
    49  	// (we are not testing pss routing here)
    50  	clients, err := setupNetwork(2)
    51  	if err != nil {
    52  		t.Fatal(err)
    53  	}
    54  
    55  	var topic string
    56  	err = clients[0].Call(&topic, "pss_stringToTopic", "foo:42")
    57  	if err != nil {
    58  		t.Fatal(err)
    59  	}
    60  
    61  	var loaddr string
    62  	err = clients[0].Call(&loaddr, "pss_baseAddr")
    63  	if err != nil {
    64  		t.Fatalf("rpc get node 1 baseaddr fail: %v", err)
    65  	}
    66  	// "0x" = 2 bytes + addrsize address bytes which in hex is 2x length
    67  	loaddr = loaddr[:2+(addrsize*2)]
    68  	var roaddr string
    69  	err = clients[1].Call(&roaddr, "pss_baseAddr")
    70  	if err != nil {
    71  		t.Fatalf("rpc get node 2 baseaddr fail: %v", err)
    72  	}
    73  	roaddr = roaddr[:2+(addrsize*2)]
    74  	log.Debug("addresses", "left", loaddr, "right", roaddr)
    75  
    76  	// retrieve public key from pss instance
    77  	// set this public key reciprocally
    78  	var lpubkey string
    79  	err = clients[0].Call(&lpubkey, "pss_getPublicKey")
    80  	if err != nil {
    81  		t.Fatalf("rpc get node 1 pubkey fail: %v", err)
    82  	}
    83  	var rpubkey string
    84  	err = clients[1].Call(&rpubkey, "pss_getPublicKey")
    85  	if err != nil {
    86  		t.Fatalf("rpc get node 2 pubkey fail: %v", err)
    87  	}
    88  
    89  	time.Sleep(time.Millisecond * 1000) // replace with hive healthy code
    90  
    91  	// give each node its peer's public key
    92  	err = clients[0].Call(nil, "pss_setPeerPublicKey", rpubkey, topic, roaddr)
    93  	if err != nil {
    94  		t.Fatal(err)
    95  	}
    96  	err = clients[1].Call(nil, "pss_setPeerPublicKey", lpubkey, topic, loaddr)
    97  	if err != nil {
    98  		t.Fatal(err)
    99  	}
   100  
   101  	// perform the handshake
   102  	// after this each side will have defaultSymKeyBufferCapacity symkeys each for in- and outgoing messages:
   103  	// L -> request 4 keys -> R
   104  	// L <- send 4 keys, request 4 keys <- R
   105  	// L -> send 4 keys -> R
   106  	// the call will fill the array with symkeys L needs for sending to R
   107  	err = clients[0].Call(nil, "pss_addHandshake", topic)
   108  	if err != nil {
   109  		t.Fatal(err)
   110  	}
   111  	err = clients[1].Call(nil, "pss_addHandshake", topic)
   112  	if err != nil {
   113  		t.Fatal(err)
   114  	}
   115  
   116  	var lhsendsymkeyids []string
   117  	err = clients[0].Call(&lhsendsymkeyids, "pss_handshake", rpubkey, topic, true, true)
   118  	if err != nil {
   119  		t.Fatal(err)
   120  	}
   121  
   122  	// make sure the r-node gets its keys
   123  	time.Sleep(time.Second)
   124  
   125  	// check if we have 6 outgoing keys stored, and they match what was received from R
   126  	var lsendsymkeyids []string
   127  	err = clients[0].Call(&lsendsymkeyids, "pss_getHandshakeKeys", rpubkey, topic, false, true)
   128  	if err != nil {
   129  		t.Fatal(err)
   130  	}
   131  	m := 0
   132  	for _, hid := range lhsendsymkeyids {
   133  		for _, lid := range lsendsymkeyids {
   134  			if lid == hid {
   135  				m++
   136  			}
   137  		}
   138  	}
   139  	if m != defaultSymKeyCapacity {
   140  		t.Fatalf("buffer size mismatch, expected %d, have %d: %v", defaultSymKeyCapacity, m, lsendsymkeyids)
   141  	}
   142  
   143  	// check if in- and outgoing keys on l-node and r-node match up and are in opposite categories (l recv = r send, l send = r recv)
   144  	var rsendsymkeyids []string
   145  	err = clients[1].Call(&rsendsymkeyids, "pss_getHandshakeKeys", lpubkey, topic, false, true)
   146  	if err != nil {
   147  		t.Fatal(err)
   148  	}
   149  	var lrecvsymkeyids []string
   150  	err = clients[0].Call(&lrecvsymkeyids, "pss_getHandshakeKeys", rpubkey, topic, true, false)
   151  	if err != nil {
   152  		t.Fatal(err)
   153  	}
   154  	var rrecvsymkeyids []string
   155  	err = clients[1].Call(&rrecvsymkeyids, "pss_getHandshakeKeys", lpubkey, topic, true, false)
   156  	if err != nil {
   157  		t.Fatal(err)
   158  	}
   159  
   160  	// get outgoing symkeys in byte form from both sides
   161  	var lsendsymkeys []string
   162  	for _, id := range lsendsymkeyids {
   163  		var key string
   164  		err = clients[0].Call(&key, "pss_getSymmetricKey", id)
   165  		if err != nil {
   166  			t.Fatal(err)
   167  		}
   168  		lsendsymkeys = append(lsendsymkeys, key)
   169  	}
   170  	var rsendsymkeys []string
   171  	for _, id := range rsendsymkeyids {
   172  		var key string
   173  		err = clients[1].Call(&key, "pss_getSymmetricKey", id)
   174  		if err != nil {
   175  			t.Fatal(err)
   176  		}
   177  		rsendsymkeys = append(rsendsymkeys, key)
   178  	}
   179  
   180  	// get incoming symkeys in byte form from both sides and compare
   181  	var lrecvsymkeys []string
   182  	for _, id := range lrecvsymkeyids {
   183  		var key string
   184  		err = clients[0].Call(&key, "pss_getSymmetricKey", id)
   185  		if err != nil {
   186  			t.Fatal(err)
   187  		}
   188  		match := false
   189  		for _, otherkey := range rsendsymkeys {
   190  			if otherkey == key {
   191  				match = true
   192  			}
   193  		}
   194  		if !match {
   195  			t.Fatalf("no match right send for left recv key %s", id)
   196  		}
   197  		lrecvsymkeys = append(lrecvsymkeys, key)
   198  	}
   199  	var rrecvsymkeys []string
   200  	for _, id := range rrecvsymkeyids {
   201  		var key string
   202  		err = clients[1].Call(&key, "pss_getSymmetricKey", id)
   203  		if err != nil {
   204  			t.Fatal(err)
   205  		}
   206  		match := false
   207  		for _, otherkey := range lsendsymkeys {
   208  			if otherkey == key {
   209  				match = true
   210  			}
   211  		}
   212  		if !match {
   213  			t.Fatalf("no match left send for right recv key %s", id)
   214  		}
   215  		rrecvsymkeys = append(rrecvsymkeys, key)
   216  	}
   217  
   218  	// send new handshake request, should send no keys
   219  	err = clients[0].Call(nil, "pss_handshake", rpubkey, topic, false)
   220  	if err == nil {
   221  		t.Fatal("expected full symkey buffer error")
   222  	}
   223  
   224  	// expire one key, send new handshake request
   225  	err = clients[0].Call(nil, "pss_releaseHandshakeKey", rpubkey, topic, lsendsymkeyids[0], true)
   226  	if err != nil {
   227  		t.Fatalf("release left send key %s fail: %v", lsendsymkeyids[0], err)
   228  	}
   229  
   230  	var newlhsendkeyids []string
   231  
   232  	// send new handshake request, should now receive one key
   233  	// check that it is not in previous right recv key array
   234  	err = clients[0].Call(&newlhsendkeyids, "pss_handshake", rpubkey, topic, true, false)
   235  	if err != nil {
   236  		t.Fatalf("handshake send fail: %v", err)
   237  	} else if len(newlhsendkeyids) != defaultSymKeyCapacity {
   238  		t.Fatalf("wrong receive count, expected 1, got %d", len(newlhsendkeyids))
   239  	}
   240  
   241  	var newlrecvsymkey string
   242  	err = clients[0].Call(&newlrecvsymkey, "pss_getSymmetricKey", newlhsendkeyids[0])
   243  	if err != nil {
   244  		t.Fatal(err)
   245  	}
   246  	var rmatchsymkeyid *string
   247  	for i, id := range rrecvsymkeyids {
   248  		var key string
   249  		err = clients[1].Call(&key, "pss_getSymmetricKey", id)
   250  		if err != nil {
   251  			t.Fatal(err)
   252  		}
   253  		if newlrecvsymkey == key {
   254  			rmatchsymkeyid = &rrecvsymkeyids[i]
   255  		}
   256  	}
   257  	if rmatchsymkeyid != nil {
   258  		t.Fatalf("right sent old key id %s in second handshake", *rmatchsymkeyid)
   259  	}
   260  
   261  	// clean the pss core keystore. Should clean the key released earlier
   262  	var cleancount int
   263  	clients[0].Call(&cleancount, "psstest_clean")
   264  	if cleancount > 1 {
   265  		t.Fatalf("pss clean count mismatch; expected 1, got %d", cleancount)
   266  	}
   267  }