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