kex_test.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // Copyright 2013 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package ssh
  5. // Key exchange tests.
  6. import (
  7. "crypto/rand"
  8. "fmt"
  9. "reflect"
  10. "sync"
  11. "testing"
  12. )
  13. // Runs multiple key exchanges concurrent to detect potential data races with
  14. // kex obtained from the global kexAlgoMap.
  15. // This test needs to be executed using the race detector in order to detect
  16. // race conditions.
  17. func TestKexes(t *testing.T) {
  18. type kexResultErr struct {
  19. result *kexResult
  20. err error
  21. }
  22. for name, kex := range kexAlgoMap {
  23. t.Run(name, func(t *testing.T) {
  24. wg := sync.WaitGroup{}
  25. for i := 0; i < 3; i++ {
  26. wg.Add(1)
  27. go func() {
  28. defer wg.Done()
  29. a, b := memPipe()
  30. s := make(chan kexResultErr, 1)
  31. c := make(chan kexResultErr, 1)
  32. var magics handshakeMagics
  33. go func() {
  34. r, e := kex.Client(a, rand.Reader, &magics)
  35. a.Close()
  36. c <- kexResultErr{r, e}
  37. }()
  38. go func() {
  39. r, e := kex.Server(b, rand.Reader, &magics, testSigners["ecdsa"].(AlgorithmSigner), testSigners["ecdsa"].PublicKey().Type())
  40. b.Close()
  41. s <- kexResultErr{r, e}
  42. }()
  43. clientRes := <-c
  44. serverRes := <-s
  45. if clientRes.err != nil {
  46. t.Errorf("client: %v", clientRes.err)
  47. }
  48. if serverRes.err != nil {
  49. t.Errorf("server: %v", serverRes.err)
  50. }
  51. if !reflect.DeepEqual(clientRes.result, serverRes.result) {
  52. t.Errorf("kex %q: mismatch %#v, %#v", name, clientRes.result, serverRes.result)
  53. }
  54. }()
  55. }
  56. wg.Wait()
  57. })
  58. }
  59. }
  60. func BenchmarkKexes(b *testing.B) {
  61. type kexResultErr struct {
  62. result *kexResult
  63. err error
  64. }
  65. for name, kex := range kexAlgoMap {
  66. b.Run(name, func(b *testing.B) {
  67. for i := 0; i < b.N; i++ {
  68. t1, t2 := memPipe()
  69. s := make(chan kexResultErr, 1)
  70. c := make(chan kexResultErr, 1)
  71. var magics handshakeMagics
  72. go func() {
  73. r, e := kex.Client(t1, rand.Reader, &magics)
  74. t1.Close()
  75. c <- kexResultErr{r, e}
  76. }()
  77. go func() {
  78. r, e := kex.Server(t2, rand.Reader, &magics, testSigners["ecdsa"].(AlgorithmSigner), testSigners["ecdsa"].PublicKey().Type())
  79. t2.Close()
  80. s <- kexResultErr{r, e}
  81. }()
  82. clientRes := <-c
  83. serverRes := <-s
  84. if clientRes.err != nil {
  85. panic(fmt.Sprintf("client: %v", clientRes.err))
  86. }
  87. if serverRes.err != nil {
  88. panic(fmt.Sprintf("server: %v", serverRes.err))
  89. }
  90. }
  91. })
  92. }
  93. }