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