github.com/annchain/OG@v0.0.9/p2p/rlpx_test.go (about) 1 // Copyright 2015 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 p2p 18 19 import ( 20 "bytes" 21 "crypto/ecdsa" 22 "crypto/rand" 23 "encoding/hex" 24 "errors" 25 "fmt" 26 "github.com/annchain/OG/common/hexutil" 27 ogcrypto2 "github.com/annchain/OG/deprecated/ogcrypto" 28 msg2 "github.com/annchain/OG/types/msg" 29 "io" 30 "io/ioutil" 31 "net" 32 "reflect" 33 "strings" 34 "testing" 35 "time" 36 37 "github.com/annchain/OG/deprecated/ogcrypto/ecies" 38 "github.com/davecgh/go-spew/spew" 39 "golang.org/x/crypto/sha3" 40 ) 41 42 func TestSharedSecret(t *testing.T) { 43 prv0, _ := ogcrypto2.GenerateKey() // = ecdsa.GenerateKey(ogcrypto.S256(), rand.Reader) 44 pub0 := &prv0.PublicKey 45 prv1, _ := ogcrypto2.GenerateKey() 46 pub1 := &prv1.PublicKey 47 48 ss0, err := ecies.ImportECDSA(prv0).GenerateShared(ecies.ImportECDSAPublic(pub1), sskLen, sskLen) 49 if err != nil { 50 return 51 } 52 ss1, err := ecies.ImportECDSA(prv1).GenerateShared(ecies.ImportECDSAPublic(pub0), sskLen, sskLen) 53 if err != nil { 54 return 55 } 56 t.Logf("Secret:\n%v %x\n%v %x", len(ss0), ss0, len(ss0), ss1) 57 if !bytes.Equal(ss0, ss1) { 58 t.Errorf("dont match :(") 59 } 60 } 61 62 func TestEncHandshake(t *testing.T) { 63 for i := 0; i < 10; i++ { 64 start := time.Now() 65 if err := testEncHandshake(nil); err != nil { 66 t.Fatalf("i=%d %v", i, err) 67 } 68 t.Logf("(without token) %d %v\n", i+1, time.Since(start)) 69 } 70 for i := 0; i < 10; i++ { 71 tok := make([]byte, shaLen) 72 rand.Reader.Read(tok) 73 start := time.Now() 74 if err := testEncHandshake(tok); err != nil { 75 t.Fatalf("i=%d %v", i, err) 76 } 77 t.Logf("(with token) %d %v\n", i+1, time.Since(start)) 78 } 79 } 80 81 func testEncHandshake(token []byte) error { 82 type result struct { 83 side string 84 pubkey *ecdsa.PublicKey 85 err error 86 } 87 var ( 88 prv0, _ = ogcrypto2.GenerateKey() 89 prv1, _ = ogcrypto2.GenerateKey() 90 fd0, fd1 = net.Pipe() 91 c0, c1 = newRLPX(fd0).(*rlpx), newRLPX(fd1).(*rlpx) 92 output = make(chan result) 93 ) 94 95 go func() { 96 r := result{side: "initiator"} 97 defer func() { output <- r }() 98 defer fd0.Close() 99 100 r.pubkey, r.err = c0.doEncHandshake(prv0, &prv1.PublicKey) 101 if r.err != nil { 102 return 103 } 104 if !reflect.DeepEqual(r.pubkey, &prv1.PublicKey) { 105 r.err = fmt.Errorf("remote pubkey mismatch: got %v, want: %v", r.pubkey, &prv1.PublicKey) 106 } 107 }() 108 go func() { 109 r := result{side: "receiver"} 110 defer func() { output <- r }() 111 defer fd1.Close() 112 113 r.pubkey, r.err = c1.doEncHandshake(prv1, nil) 114 if r.err != nil { 115 return 116 } 117 if !reflect.DeepEqual(r.pubkey, &prv0.PublicKey) { 118 r.err = fmt.Errorf("remote ID mismatch: got %v, want: %v", r.pubkey, &prv0.PublicKey) 119 } 120 }() 121 122 // wait for results from both sides 123 r1, r2 := <-output, <-output 124 if r1.err != nil { 125 return fmt.Errorf("%s side error: %v", r1.side, r1.err) 126 } 127 if r2.err != nil { 128 return fmt.Errorf("%s side error: %v", r2.side, r2.err) 129 } 130 131 // compare derived secrets 132 if !reflect.DeepEqual(c0.rw.egressMAC, c1.rw.ingressMAC) { 133 return fmt.Errorf("egress mac mismatch:\n c0.rw: %#v\n c1.rw: %#v", c0.rw.egressMAC, c1.rw.ingressMAC) 134 } 135 if !reflect.DeepEqual(c0.rw.ingressMAC, c1.rw.egressMAC) { 136 return fmt.Errorf("ingress mac mismatch:\n c0.rw: %#v\n c1.rw: %#v", c0.rw.ingressMAC, c1.rw.egressMAC) 137 } 138 if !reflect.DeepEqual(c0.rw.enc, c1.rw.enc) { 139 return fmt.Errorf("enc cipher mismatch:\n c0.rw: %#v\n c1.rw: %#v", c0.rw.enc, c1.rw.enc) 140 } 141 if !reflect.DeepEqual(c0.rw.dec, c1.rw.dec) { 142 return fmt.Errorf("dec cipher mismatch:\n c0.rw: %#v\n c1.rw: %#v", c0.rw.dec, c1.rw.dec) 143 } 144 return nil 145 } 146 147 /* 148 func TestProtocolHandshake(t *testing.T) { 149 var ( 150 prv0, _ = ogcrypto.GenerateKey() 151 node0 = &discover.Node{ID: discover.PubkeyID(&prv0.PublicKey), IP: net.IP{1, 2, 3, 4}, TCP: 33} 152 hs0 = &protoHandshake{Version: 3, ID: node0.ID, Caps: []Cap{{"a", 0}, {"b", 2}}} 153 154 prv1, _ = ogcrypto.GenerateKey() 155 node1 = &discover.Node{ID: discover.PubkeyID(&prv1.PublicKey), IP: net.IP{5, 6, 7, 8}, TCP: 44} 156 hs1 = &protoHandshake{Version: 3, ID: node1.ID, Caps: []Cap{{"c", 1}, {"d", 3}}} 157 158 wg sync.WaitGroup 159 ) 160 161 fd0, fd1, err := pipes.TCPPipe() 162 if err != nil { 163 t.Fatal(err) 164 } 165 166 wg.Add(2) 167 go func() { 168 defer wg.Done() 169 defer fd0.Close() 170 rlpx := newRLPX(fd0) 171 remid, err := rlpx.doEncHandshake(prv0, node1) 172 if err != nil { 173 t.Errorf("dial side enc handshake failed: %v", err) 174 return 175 } 176 if remid != node1.ID { 177 t.Errorf("dial side remote id mismatch: got %v, want %v", remid, node1.ID) 178 return 179 } 180 181 phs, err := rlpx.doProtoHandshake(hs0) 182 if err != nil { 183 t.Errorf("dial side proto handshake error: %v", err) 184 return 185 } 186 phs.Rest = nil 187 if !reflect.DeepEqual(phs, hs1) { 188 t.Errorf("dial side proto handshake mismatch:\ngot: %s\nwant: %s\n", spew.Sdump(phs), spew.Sdump(hs1)) 189 return 190 } 191 rlpx.close(DiscQuitting) 192 }() 193 go func() { 194 defer wg.Done() 195 defer fd1.Close() 196 rlpx := newRLPX(fd1) 197 remid, err := rlpx.doEncHandshake(prv1, nil) 198 if err != nil { 199 t.Errorf("listen side enc handshake failed: %v", err) 200 return 201 } 202 if remid != node0.ID { 203 t.Errorf("listen side remote id mismatch: got %v, want %v", remid, node0.ID) 204 return 205 } 206 207 phs, err := rlpx.doProtoHandshake(hs1) 208 if err != nil { 209 t.Errorf("listen side proto handshake error: %v", err) 210 return 211 } 212 phs.Rest = nil 213 if !reflect.DeepEqual(phs, hs0) { 214 t.Errorf("listen side proto handshake mismatch:\ngot: %s\nwant: %s\n", spew.Sdump(phs), spew.Sdump(hs0)) 215 return 216 } 217 218 if err := ExpectMsg(rlpx, discMsg, []DiscReason{DiscQuitting}); err != nil { 219 t.Errorf("error receiving disconnect: %v", err) 220 } 221 }() 222 wg.Wait() 223 } 224 */ 225 func TestProtocolHandshakeErrors(t *testing.T) { 226 our := &ProtoHandshake{Version: 3, Caps: []Cap{{"foo", 2}, {"bar", 3}}, Name: "quux"} 227 quitData, _ := DiscQuitting.MarshalMsg(nil) 228 pro := ProtoHandshake{Version: 3} 229 protoData, _ := pro.MarshalMsg(nil) 230 tests := []struct { 231 code MsgCodeType 232 //msg interface{} 233 msg []byte 234 err error 235 }{ 236 { 237 code: discMsg, 238 //msg: []DiscReason{DiscQuitting}, 239 msg: quitData, 240 err: DiscQuitting, 241 }, 242 { 243 code: 0x9898, 244 msg: []byte{1}, 245 err: errors.New("expected handshake, got 989898"), 246 }, 247 { 248 code: handshakeMsg, 249 msg: make([]byte, baseProtocolMaxMsgSize+2), 250 err: errors.New("message too big"), 251 }, 252 { 253 code: handshakeMsg, 254 msg: []byte{1, 2, 3}, 255 err: newPeerError(errInvalidMsg, "(code 0) (size 3) msgp: attempted to decode type \"int\" with method for \"map\""), 256 }, 257 { 258 code: handshakeMsg, 259 //msg: &ProtoHandshake{Version: 3}, 260 msg: protoData, 261 err: DiscInvalidIdentity, 262 }, 263 } 264 265 for i, test := range tests { 266 p1, p2 := MsgPipe() 267 go Send(p1, test.code, test.msg) 268 _, err := readProtocolHandshake(p2, our) 269 if !reflect.DeepEqual(err, test.err) { 270 t.Errorf("test %d: error mismatch: got %q, want %q", i, err, test.err) 271 } 272 } 273 } 274 275 func TestRlpxFrameRW_ReadMsg(t *testing.T) { 276 buf := new(bytes.Buffer) 277 hash := fakeHash([]byte{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}) 278 rw := newRLPXFrameRW(buf, secrets{ 279 AES: ogcrypto2.Keccak256(), 280 MAC: ogcrypto2.Keccak256(), 281 IngressMAC: hash, 282 EgressMAC: hash, 283 }) 284 golden := unhex(`0082bbdae471818bb0bfa6b551d1cb4201010101010101010101010101010101ba 285 62a6f3941e80e6674fccb640b769410ca260cb7b00 286 9e5b45d021af17dc638f146f174d0e5ff380abf27f3a87a6e4f101010101010101010101010101010101`) 287 // Check WriteMsg. This puts a message into the buffer. 288 a := msg2.Bytes(unhex("ba328a4ba590cb43f7848f41c438288500828ddae471818bb0bfa6b551d1cb42465456465485658686555555ab")) 289 b, _ := a.MarshalMsg(nil) 290 fmt.Println(hexutil.Encode(b), len(b)) 291 if err := Send(rw, 8, b); err != nil { 292 t.Fatalf("WriteMsg error: %v", err) 293 } 294 var code MsgCodeType 295 code = 8 296 codeM, _ := code.MarshalMsg(nil) 297 fmt.Println(codeM, len(codeM)) 298 written := buf.Bytes() 299 fmt.Println(len(written), hex.EncodeToString(written)) 300 if !bytes.Equal(written, golden) { 301 t.Fatalf("output mismatch:\n got: %x\n want: %x", written, golden) 302 } 303 // Check ReadMsg. It reads the message encoded by WriteMsg, which 304 // is equivalent to the golden message above. 305 msg, err := rw.ReadMsg() 306 if err != nil { 307 t.Fatalf("ReadMsg error: %v", err) 308 } 309 if msg.Size != 47 { 310 t.Errorf("msg size mismatch: got %d, want %d", msg.Size, 47) 311 } 312 fmt.Println("siez ", msg.Size) 313 if msg.Code != 8 { 314 t.Errorf("msg code mismatch: got %d, want %d", msg.Code, 8) 315 } 316 payload, _ := ioutil.ReadAll(msg.Payload) 317 wantPayload := unhex("c42dba328a4ba590cb43f7848f41c438288500828ddae471818bb0bfa6b551d1cb42465456465485658686555555ab") 318 if !bytes.Equal(payload, wantPayload) { 319 t.Errorf("msg payload mismatch:\ngot %x\nwant %x", payload, wantPayload) 320 } 321 } 322 323 func TestRLPXFrameFake(t *testing.T) { 324 buf := new(bytes.Buffer) 325 hash := fakeHash([]byte{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}) 326 rw := newRLPXFrameRW(buf, secrets{ 327 AES: ogcrypto2.Keccak256(), 328 MAC: ogcrypto2.Keccak256(), 329 IngressMAC: hash, 330 EgressMAC: hash, 331 }) 332 333 golden := unhex(` 334 00828ddae471818bb0bfa6b551d1cb42 335 01010101010101010101010101010101 336 ba328a4ba590cb43f7848f41c4382885 337 01010101010101010101010101010101 338 `) 339 340 // Check WriteMsg. This puts a message into the buffer. 341 a := msg2.Uints{1, 2, 3, 4} 342 b, _ := a.MarshalMsg(nil) 343 if err := Send(rw, 8, b); err != nil { 344 t.Fatalf("WriteMsg error: %v", err) 345 } 346 written := buf.Bytes() 347 if !bytes.Equal(written, golden) { 348 t.Fatalf("output mismatch:\n got: %x\n want: %x", written, golden) 349 } 350 351 // Check ReadMsg. It reads the message encoded by WriteMsg, which 352 // is equivalent to the golden message above. 353 msg, err := rw.ReadMsg() 354 if err != nil { 355 t.Fatalf("ReadMsg error: %v", err) 356 } 357 if msg.Size != 5 { 358 t.Errorf("msg size mismatch: got %d, want %d", msg.Size, 5) 359 } 360 if msg.Code != 8 { 361 t.Errorf("msg code mismatch: got %d, want %d", msg.Code, 8) 362 } 363 payload, _ := ioutil.ReadAll(msg.Payload) 364 wantPayload := unhex("9401020304") 365 if !bytes.Equal(payload, wantPayload) { 366 t.Errorf("msg payload mismatch:\ngot %x\nwant %x", payload, wantPayload) 367 } 368 } 369 370 type fakeHash []byte 371 372 func (fakeHash) Write(p []byte) (int, error) { return len(p), nil } 373 func (fakeHash) Reset() {} 374 func (fakeHash) BlockSize() int { return 0 } 375 376 func (h fakeHash) Size() int { return len(h) } 377 func (h fakeHash) Sum(b []byte) []byte { return append(b, h...) } 378 379 func TestRLPXFrameRW(t *testing.T) { 380 var ( 381 aesSecret = make([]byte, 16) 382 macSecret = make([]byte, 16) 383 egressMACinit = make([]byte, 32) 384 ingressMACinit = make([]byte, 32) 385 ) 386 for _, s := range [][]byte{aesSecret, macSecret, egressMACinit, ingressMACinit} { 387 rand.Read(s) 388 } 389 conn := new(bytes.Buffer) 390 391 s1 := secrets{ 392 AES: aesSecret, 393 MAC: macSecret, 394 EgressMAC: sha3.NewLagecyKeccak256()(), 395 IngressMAC: sha3.NewLegacyKeccak256(), 396 } 397 s1.EgressMAC.Write(egressMACinit) 398 s1.IngressMAC.Write(ingressMACinit) 399 rw1 := newRLPXFrameRW(conn, s1) 400 401 s2 := secrets{ 402 AES: aesSecret, 403 MAC: macSecret, 404 EgressMAC: sha3.NewLegacyKeccak256(), 405 IngressMAC: sha3.NewLegacyKeccak256(), 406 } 407 s2.EgressMAC.Write(ingressMACinit) 408 s2.IngressMAC.Write(egressMACinit) 409 rw2 := newRLPXFrameRW(conn, s2) 410 411 // send some messages 412 for i := 0; i < 10; i++ { 413 // write message into conn buffer 414 wmsg := msg2.Strings{"foo", "bar", strings.Repeat("test", i)} 415 b, _ := wmsg.MarshalMsg(nil) 416 err := Send(rw1, MsgCodeType(i), b) 417 if err != nil { 418 t.Fatalf("WriteMsg error (i=%d): %v", i, err) 419 } 420 421 // read message that rw1 just wrote 422 msg, err := rw2.ReadMsg() 423 if err != nil { 424 t.Fatalf("ReadMsg error (i=%d): %v", i, err) 425 } 426 if msg.Code != MsgCodeType(i) { 427 t.Fatalf("msg code mismatch: got %d, want %d", msg.Code, i) 428 } 429 payload, _ := ioutil.ReadAll(msg.Payload) 430 wantPayload, _ := wmsg.MarshalMsg(nil) 431 //wantPayload, _ := rlp.EncodeToBytes(wmsg) 432 if !bytes.Equal(payload, wantPayload) { 433 t.Fatalf("msg payload mismatch:\ngot %x\nwant %x", payload, wantPayload) 434 } 435 } 436 } 437 438 type handshakeAuthTest struct { 439 input string 440 isPlain bool 441 wantVersion uint 442 wantRest [][]byte 443 } 444 445 var eip8HandshakeAuthTests = []handshakeAuthTest{ 446 // (Auth₁) RLPx v4 plain encoding 447 { 448 input: ` 449 048ca79ad18e4b0659fab4853fe5bc58eb83992980f4c9cc147d2aa31532efd29a3d3dc6a3d89eaf 450 913150cfc777ce0ce4af2758bf4810235f6e6ceccfee1acc6b22c005e9e3a49d6448610a58e98744 451 ba3ac0399e82692d67c1f58849050b3024e21a52c9d3b01d871ff5f210817912773e610443a9ef14 452 2e91cdba0bd77b5fdf0769b05671fc35f83d83e4d3b0b000c6b2a1b1bba89e0fc51bf4e460df3105 453 c444f14be226458940d6061c296350937ffd5e3acaceeaaefd3c6f74be8e23e0f45163cc7ebd7622 454 0f0128410fd05250273156d548a414444ae2f7dea4dfca2d43c057adb701a715bf59f6fb66b2d1d2 455 0f2c703f851cbf5ac47396d9ca65b6260bd141ac4d53e2de585a73d1750780db4c9ee4cd4d225173 456 a4592ee77e2bd94d0be3691f3b406f9bba9b591fc63facc016bfa8 457 `, 458 isPlain: true, 459 wantVersion: 4, 460 }, 461 // (Auth₂) EIP-8 encoding 462 { 463 input: ` 464 01fd04e21891e689df83f64e0f6fd092c3060aeaebeae4abd52898524a6dde5167 465 aeecce9bc44234c8953db2b084ee7f8f0773e43861469cc1021b2154aed092988d49ff079abe 466 52b24069b344b08e0680dd0d388b53e2651f86259c91eaad261e09d5be94c070f91c0ae3cb1af 467 fa11017aabdc223a5919596da1999260715eda05f3653623c05350fa7bf06dcde5a754066f8d4 468 64a3fa99c47d50e0ff3b7b58ad43e85ceaca2646cc36206e0b0648b92604b6593559d202d1b294 469 60af08d6818decf069118ded9eaabac157fa77494b90c23d94a3932694bbdd65abcfbe44000b 470 1b5e19dec5345968756f7be241b614f239613bfd1b073d23f83bb9916013f02bd815800cdded 471 09c429ced8526d0b433bf400e54eb30ec5ce9dc6f96a75dee773afbbb73d64ffc9dc5db4080a 472 5571b3ad9122f67a24815e53d43522209606800d9ff8dd29411ce279d40ec12f202370356396 473 62248f1ce553bab7b35aa13bd76a0ae435fc3515a5708b4f8f71af5bf96657e04d572850c6cb 474 241fc2dccdfd4f9fc04ce5d53e6e502f2fc9477aabaa829ee26e2e2f377a434d5e2e6e6632b 475 8100013c90c05828fa14e6dbc2d32a10eed51877ad5cf06396220bab227405f48dc725c2bc 476 2281f762212dc192d672cb5bc3289ac50a0244c68d33f509d49d8789744464dc2909fffda0 477 31155bad633ad7b30eb43263aa565c086f326a8cea4c5 478 `, 479 wantVersion: 4, 480 //wantRest: [][]byte{}, 481 }, 482 // (Auth₃) RLPx v4 EIP-8 encoding with version 56, additional list elements 483 { 484 input: ` 485 020e0439c7b8803f6c8939c83ab2e024093a2ab2e5834512f47bf84aa33439f03539053a84cec7469803d 486 4edeeea66059be82d4fa0aa419d3ab77631c228f1936e27e57ce6c5dc9a785fd19892367ecb21a716fbf8d 487 498280924d63c2b27977797ff71742fa9960f8e9f6571045c5a1e812644f541221aac59c5e27d5daba1f8119db944f 488 1466d6c0e068bbd7621b18ec237be63ed26f0e5b664b3395d344a3c0c57d89653816329e9e2ffd79e01ce4b5614ea 489 e80755e0aca3655eb3a435c1e7a443e0af36a9908b3dd076d01905d4c9224e0f941ebdd51e8d4 490 7fb4f495ea88c928e176ced61917da8f18bcca3365970df65f357d099dc720fdaf4aa3aaaf779af0074425551c38222c2899353028d92bf 491 ecf2b8003cf35d4bcc9ce2a25dcdc79d79cc0022835515938a59ee79bfbd78c6bef57fda03c0c42231783c7445015f247a248cdcd5a61a2 492 e108929197d3e0e83bd6d2f025115fb21e890193b3c752880a6e1758e5ded5633d81de771f68659e77511b36bac3892868148a332c3d9fb 493 1f6e060a94c10d6466ab43d44b7fde993aba6542a3d16ddbbf1308ff8b4ad04ec3b9856953931e3b18d15036deb415796fb3ec06cfb9341 494 c0072a1d60d1f416b57fd7d7800ad6923b4497aeb3210f5af001f731c7c65a22b282eecfdc6da46fa9c482a22ffa9c86073a2caf2f4da1 495 550fd79c43a03824a4932f032e8d3828844a02fab8eede2030c8d9fb0ea0a408699 496 `, 497 wantVersion: 56, 498 wantRest: [][]byte{{0x01}, {0x02}, {0xC2, 0x04, 0x05}}, 499 }, 500 } 501 502 type handshakeAckTest struct { 503 input string 504 wantVersion uint 505 wantRest [][]byte 506 } 507 508 var eip8HandshakeRespTests = []handshakeAckTest{ 509 // (Ack₁) RLPx v4 plain encoding 510 { 511 input: ` 512 049f8abcfa9c0dc65b982e98af921bc0ba6e4243169348a236abe9df5f93aa69d99cadddaa387662 513 b0ff2c08e9006d5a11a278b1b3331e5aaabf0a32f01281b6f4ede0e09a2d5f585b26513cb794d963 514 5a57563921c04a9090b4f14ee42be1a5461049af4ea7a7f49bf4c97a352d39c8d02ee4acc416388c 515 1c66cec761d2bc1c72da6ba143477f049c9d2dde846c252c111b904f630ac98e51609b3b1f58168d 516 dca6505b7196532e5f85b259a20c45e1979491683fee108e9660edbf38f3add489ae73e3dda2c71b 517 d1497113d5c755e942d1 518 `, 519 wantVersion: 4, 520 }, 521 // (Ack₂) EIP-8 encoding 522 { 523 input: ` 524 0197047250f566862bb97317b79c342e96f8b7ac4deedb677a687b6914dccdb7f283e0ae2ddff9efc799c8d0804ca6 525 2fbc0681ae93d5e3d4fdbcf573e75bf0fb0237456335bccfeabb0de09cbab881fc055eb1a86b455df2fc0b75d88978 526 9bb5c8887eed760079a6d0df3cee6947d3f58b6f7fb4a8999bb21bfbf218fdb06a43cc78d1bc48a513999860e8ea99 527 ff3c1f5182fe89a4df4f3c5b3c578bdc4ec64334f09f78ee3158e6162da9515bb6dd30a9b9d48e78c5f2a6c076e212 528 41b2a39ea04c439a3d9567ee27e76dc3b89484bf6305536a0485a5e4859c78370b315b57f9f72fd78e880bdbff1b13 529 b4f750e0343056bed0190cab1da47af608d9fc6cc4f41f631b4a312e5541b89b57e5472407ba5543b1e624b266a597 530 99a08595b0dbae70bde98718abe5bd361cb396f5e9fc0b04f0157cd9bf002075a27a4b7e86a6c8a6895831d4d366b3 531 1204ef1112b53c1aac130a2a1477a952a3b346154f02cd609e90545a4e12a0df4f8a1cf39296ab2b319aa7d61952d6d9 532 2f8173f5d8081e8c69e05ca50ec9e831bb3ce5301100ee9e975f0ef34db54a30 533 `, 534 wantVersion: 4, 535 //wantRest: [][]byte{}, 536 }, 537 // (Ack₃) EIP-8 encoding with version 57, additional list elements 538 { 539 input: ` 540 01b90454cd2aa35b7e6b4498bff8297dde8394fe1184cc72b4d09bfba53b5f23da6b7a265db5b6ff40e954f7 541 f0fd4c4a5466ed7a1ac15d6d7904f8aafa9c3d965a84e405e7da79dd1150bd0b17036697a6dfcd6a36a5819b45a706a3955f 542 bb247d9fb1d7a3fa2d93088d7d4f34f99a5dc889033251b953b41c4d3c89633947b0bdf836ea908d4e290db26b76b7d2a403 543 25c3e54373d7a654cb6839cb42fccf815763db6800268a5609643cb43ff32f7e20ccfe2a448c726cf8196e4327a071abaee5 544 255a6d9b42807e87a322d4dccd155ef9cd1f02ca38c5dc3a8cf12272247449e85760db4042ce08f94729a02c36bae454e99c 545 ba0ec489dd9ebc747b41ae38854605bd40e92c758403dec8dbc3b76422970015f3a63b7fa5d077cfd353dc06a0d01263ad59 546 da6da1acd564f9d4a062c5569e111950307f90cf594980cc0d5ee7daa1a85218c94759243a7a0510e32dc2ad4a23c4c201f7 547 bab86a05baa126ce572b01d345f21c6011b9e2aebad983b3beaaa66c2a4c729012ca691b9fe38cbe2b97c0a7120b85fdcd27 548 2343b4116b98a71d535b471bb61a704f553ba4bfb70dbd77f6226262ed90135b842c23ae152e84aac09feb991ba04aacbe 549 `, 550 wantVersion: 57, 551 wantRest: [][]byte{{0x06}, {0xC2, 0x07, 0x08}, {0x81, 0xFA}}, 552 }, 553 } 554 555 func TestHandshakeForwardCompatibility(t *testing.T) { 556 var ( 557 keyA, _ = ogcrypto2.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee") 558 keyB, _ = ogcrypto2.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 559 pubA = ogcrypto2.FromECDSAPub(&keyA.PublicKey)[1:] 560 pubB = ogcrypto2.FromECDSAPub(&keyB.PublicKey)[1:] 561 ephA, _ = ogcrypto2.HexToECDSA("869d6ecf5211f1cc60418a13b9d870b22959d0c16f02bec714c960dd2298a32d") 562 ephB, _ = ogcrypto2.HexToECDSA("e238eb8e04fee6511ab04c6dd3c89ce097b11f25d584863ac2b6d5b35b1847e4") 563 ephPubA = ogcrypto2.FromECDSAPub(&ephA.PublicKey)[1:] 564 ephPubB = ogcrypto2.FromECDSAPub(&ephB.PublicKey)[1:] 565 nonceA = unhex("7e968bba13b6c50e2c4cd7f241cc0d64d1ac25c7f5952df231ac6a2bda8ee5d6") 566 nonceB = unhex("559aead08264d5795d3909718cdd05abd49572e84fe55590eef31a88a08fdffd") 567 _, _, _, _ = pubA, pubB, ephPubA, ephPubB 568 authSignature = unhex("299ca6acfd35e3d72d8ba3d1e2b60b5561d5af5218eb5bc182045769eb4226910a301acae3b369fffc4a4899d6b02531e89fd4fe36a2cf0d93607ba470b50f7800") 569 _ = authSignature 570 ) 571 makeAuth := func(test handshakeAuthTest) *AuthMsgV4 { 572 msg := &AuthMsgV4{Version: test.wantVersion, Rest: test.wantRest, gotPlain: test.isPlain} 573 copy(msg.Signature[:], authSignature) 574 copy(msg.InitiatorPubkey[:], pubA) 575 copy(msg.Nonce[:], nonceA) 576 return msg 577 } 578 makeAck := func(test handshakeAckTest) *AuthRespV4 { 579 msg := &AuthRespV4{Version: test.wantVersion, Rest: test.wantRest} 580 copy(msg.RandomPubkey[:], ephPubB) 581 copy(msg.Nonce[:], nonceB) 582 return msg 583 } 584 585 // check auth msg parsing 586 for _, test := range eip8HandshakeAuthTests { 587 r := bytes.NewReader(unhex(test.input)) 588 msg := new(AuthMsgV4) 589 /* 590 var someText []byte 591 msg2 := makeAuth(test) 592 pub_b:= ecies.ImportECDSAPublic(&keyB.PublicKey) 593 if !msg2.gotPlain{ 594 someText,_= preEip8test(msg2,pub_b) 595 r2 := bytes.NewReader(someText) 596 fmt.Println(r2.Size()) 597 } 598 599 */ 600 ciphertext, err := readHandshakeMsg(msg, encAuthMsgLen, keyB, r) 601 if err != nil { 602 t.Errorf("error for input %x:\n %v ", unhex(test.input), err) 603 continue 604 } 605 if !bytes.Equal(ciphertext, unhex(test.input)) { 606 t.Errorf("wrong ciphertext for input %x:\n %x", unhex(test.input), ciphertext) 607 } 608 want := makeAuth(test) 609 if !reflect.DeepEqual(msg, want) { 610 t.Errorf("wrong msg for input %x:\ngot %s\nwant %s", unhex(test.input), spew.Sdump(msg), spew.Sdump(want)) 611 fmt.Println(msg.Version != want.Version, msg.gotPlain) 612 } 613 } 614 615 // check auth resp parsing 616 for _, test := range eip8HandshakeRespTests { 617 input := unhex(test.input) 618 r := bytes.NewReader(input) 619 msg := new(AuthRespV4) 620 /* 621 var someText []byte 622 msg2 := makeAck(test) 623 pub_a:= ecies.ImportECDSAPublic(&keyA.PublicKey) 624 625 someText,_= preEip8Resptest(msg2,pub_a) 626 r = bytes.NewReader(someText) 627 fmt.Println(r.Size()) 628 629 */ 630 ciphertext, err := readHandshakeMsgResp(msg, encAuthRespLen, keyA, r) 631 if err != nil { 632 t.Errorf("error for input %x:\n %v", input, err) 633 continue 634 } 635 if !bytes.Equal(ciphertext, input) { 636 t.Errorf("wrong ciphertext for input %x:\n %x", input, ciphertext) 637 } 638 want := makeAck(test) 639 if !reflect.DeepEqual(msg, want) { 640 t.Errorf("wrong msg for input %x:\ngot %s\nwant %s", input, spew.Sdump(msg), spew.Sdump(want)) 641 } 642 } 643 644 // check derivation for (Auth₂, Ack₂) on recipient side 645 var ( 646 hs = &encHandshake{ 647 initiator: false, 648 respNonce: nonceB, 649 randomPrivKey: ecies.ImportECDSA(ephB), 650 } 651 authCiphertext = unhex(eip8HandshakeAuthTests[1].input) 652 authRespCiphertext = unhex(eip8HandshakeRespTests[1].input) 653 authMsg = makeAuth(eip8HandshakeAuthTests[1]) 654 wantAES = unhex("80e8632c05fed6fc2a13b0f8d31a3cf645366239170ea067065aba8e28bac487") 655 wantMAC = unhex("2ea74ec5dae199227dff1af715362700e989d889d7a493cb0639691efb8e5f98") 656 //wantFooIngressHash = unhex("0c7ec6340062cc46f5e9f1e3cf86f8c8c403c5a0964f5df0ebd34a75ddc86db5") 657 wantFooIngressHash = unhex("d402a923042e8aab1f01f0783c343d574d3a0d70872e874168ea4d6174129e77") 658 ) 659 if err := hs.handleAuthMsg(authMsg, keyB); err != nil { 660 t.Fatalf("handleAuthMsg: %v", err) 661 } 662 derived, err := hs.secrets(authCiphertext, authRespCiphertext) 663 if err != nil { 664 t.Fatalf("secrets: %v", err) 665 } 666 if !bytes.Equal(derived.AES, wantAES) { 667 t.Errorf("aes-secret mismatch:\ngot %x\nwant %x", derived.AES, wantAES) 668 } 669 if !bytes.Equal(derived.MAC, wantMAC) { 670 t.Errorf("mac-secret mismatch:\ngot %x\nwant %x", derived.MAC, wantMAC) 671 } 672 io.WriteString(derived.IngressMAC, "foo") 673 fooIngressHash := derived.IngressMAC.Sum(nil) 674 if !bytes.Equal(fooIngressHash, wantFooIngressHash) { 675 t.Errorf("ingress-mac('foo') mismatch:\ngot %x\nwant %x", fooIngressHash, wantFooIngressHash) 676 } 677 }