You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

107 lines
2.7 KiB

  1. package secretconnection
  2. import (
  3. "bytes"
  4. "fmt"
  5. "io"
  6. "log"
  7. "github.com/tendermint/tendermint/crypto/ed25519"
  8. "github.com/tendermint/tendermint/libs/async"
  9. sc "github.com/tendermint/tendermint/p2p/conn"
  10. )
  11. func Fuzz(data []byte) int {
  12. if len(data) == 0 {
  13. return -1
  14. }
  15. fooConn, barConn := makeSecretConnPair()
  16. n, err := fooConn.Write(data)
  17. if err != nil {
  18. panic(err)
  19. }
  20. dataRead := make([]byte, n)
  21. m, err := barConn.Read(dataRead)
  22. if err != nil {
  23. panic(err)
  24. }
  25. if !bytes.Equal(data[:n], dataRead[:m]) {
  26. panic(fmt.Sprintf("bytes written %X != read %X", data[:n], dataRead[:m]))
  27. }
  28. return 1
  29. }
  30. type kvstoreConn struct {
  31. *io.PipeReader
  32. *io.PipeWriter
  33. }
  34. func (drw kvstoreConn) Close() (err error) {
  35. err2 := drw.PipeWriter.CloseWithError(io.EOF)
  36. err1 := drw.PipeReader.Close()
  37. if err2 != nil {
  38. return err
  39. }
  40. return err1
  41. }
  42. // Each returned ReadWriteCloser is akin to a net.Connection
  43. func makeKVStoreConnPair() (fooConn, barConn kvstoreConn) {
  44. barReader, fooWriter := io.Pipe()
  45. fooReader, barWriter := io.Pipe()
  46. return kvstoreConn{fooReader, fooWriter}, kvstoreConn{barReader, barWriter}
  47. }
  48. func makeSecretConnPair() (fooSecConn, barSecConn *sc.SecretConnection) {
  49. var (
  50. fooConn, barConn = makeKVStoreConnPair()
  51. fooPrvKey = ed25519.GenPrivKey()
  52. fooPubKey = fooPrvKey.PubKey()
  53. barPrvKey = ed25519.GenPrivKey()
  54. barPubKey = barPrvKey.PubKey()
  55. )
  56. // Make connections from both sides in parallel.
  57. var trs, ok = async.Parallel(
  58. func(_ int) (val interface{}, abort bool, err error) {
  59. fooSecConn, err = sc.MakeSecretConnection(fooConn, fooPrvKey)
  60. if err != nil {
  61. log.Printf("failed to establish SecretConnection for foo: %v", err)
  62. return nil, true, err
  63. }
  64. remotePubBytes := fooSecConn.RemotePubKey()
  65. if !remotePubBytes.Equals(barPubKey) {
  66. err = fmt.Errorf("unexpected fooSecConn.RemotePubKey. Expected %v, got %v",
  67. barPubKey, fooSecConn.RemotePubKey())
  68. log.Print(err)
  69. return nil, true, err
  70. }
  71. return nil, false, nil
  72. },
  73. func(_ int) (val interface{}, abort bool, err error) {
  74. barSecConn, err = sc.MakeSecretConnection(barConn, barPrvKey)
  75. if barSecConn == nil {
  76. log.Printf("failed to establish SecretConnection for bar: %v", err)
  77. return nil, true, err
  78. }
  79. remotePubBytes := barSecConn.RemotePubKey()
  80. if !remotePubBytes.Equals(fooPubKey) {
  81. err = fmt.Errorf("unexpected barSecConn.RemotePubKey. Expected %v, got %v",
  82. fooPubKey, barSecConn.RemotePubKey())
  83. log.Print(err)
  84. return nil, true, err
  85. }
  86. return nil, false, nil
  87. },
  88. )
  89. if trs.FirstError() != nil {
  90. log.Fatalf("unexpected error: %v", trs.FirstError())
  91. }
  92. if !ok {
  93. log.Fatal("Unexpected task abortion")
  94. }
  95. return fooSecConn, barSecConn
  96. }