authPackage_test.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /*
  2. * Copyright (c) 2016, Psiphon Inc.
  3. * All rights reserved.
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. *
  18. */
  19. package common
  20. import (
  21. "encoding/base64"
  22. "encoding/json"
  23. "io"
  24. "io/ioutil"
  25. "math/rand"
  26. "os"
  27. "testing"
  28. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/errors"
  29. )
  30. func TestAuthenticatedPackage(t *testing.T) {
  31. signingPublicKey, signingPrivateKey, err := GenerateAuthenticatedDataPackageKeys()
  32. if err != nil {
  33. t.Fatalf("GenerateAuthenticatedDataPackageKeys failed: %s", err)
  34. }
  35. expectedContent := "TestAuthenticatedPackage"
  36. packagePayload, err := WriteAuthenticatedDataPackage(
  37. expectedContent,
  38. signingPublicKey,
  39. signingPrivateKey)
  40. if err != nil {
  41. t.Fatalf("WriteAuthenticatedDataPackage failed: %s", err)
  42. }
  43. tempFileName, err := makeTempFile(packagePayload)
  44. if err != nil {
  45. t.Fatalf("makeTempFile failed: %s", err)
  46. }
  47. defer os.Remove(tempFileName)
  48. wrongSigningPublicKey, _, err := GenerateAuthenticatedDataPackageKeys()
  49. if err != nil {
  50. t.Fatalf("GenerateAuthenticatedDataPackageKeys failed: %s", err)
  51. }
  52. packageJSON, err := Decompress(packagePayload)
  53. if err != nil {
  54. t.Fatalf("Uncompress failed: %s", err)
  55. }
  56. var authDataPackage AuthenticatedDataPackage
  57. err = json.Unmarshal(packageJSON, &authDataPackage)
  58. if err != nil {
  59. t.Fatalf("Unmarshal failed: %s", err)
  60. }
  61. authDataPackage.Data = "TamperedData"
  62. tamperedPackageJSON, err := json.Marshal(&authDataPackage)
  63. if err != nil {
  64. t.Fatalf("Marshal failed: %s", err)
  65. }
  66. tamperedPackagePayload := Compress(tamperedPackageJSON)
  67. tamperedTempFileName, err := makeTempFile(tamperedPackagePayload)
  68. if err != nil {
  69. t.Fatalf("makeTempFile failed: %s", err)
  70. }
  71. defer os.Remove(tempFileName)
  72. t.Run("read package: success", func(t *testing.T) {
  73. content, err := ReadAuthenticatedDataPackage(
  74. packagePayload, true, signingPublicKey)
  75. if err != nil {
  76. t.Fatalf("ReadAuthenticatedDataPackage failed: %s", err)
  77. }
  78. if content != expectedContent {
  79. t.Fatalf(
  80. "unexpected package content: expected %s got %s",
  81. expectedContent, content)
  82. }
  83. })
  84. t.Run("streaming read package: success", func(t *testing.T) {
  85. file, err := os.Open(tempFileName)
  86. if err != nil {
  87. t.Fatalf("Open failed: %s", err)
  88. }
  89. defer file.Close()
  90. contentReader, err := NewAuthenticatedDataPackageReader(
  91. file, signingPublicKey)
  92. if err != nil {
  93. t.Fatalf("NewAuthenticatedDataPackageReader failed: %s", err)
  94. }
  95. content, err := ioutil.ReadAll(contentReader)
  96. if err != nil {
  97. t.Fatalf("ReadAll failed: %s", err)
  98. }
  99. if string(content) != expectedContent {
  100. t.Fatalf(
  101. "unexpected package content: expected %s got %s",
  102. expectedContent, content)
  103. }
  104. })
  105. t.Run("read package: wrong signing key", func(t *testing.T) {
  106. _, err = ReadAuthenticatedDataPackage(
  107. packagePayload, true, wrongSigningPublicKey)
  108. if err == nil {
  109. t.Fatalf("ReadAuthenticatedDataPackage unexpectedly succeeded")
  110. }
  111. })
  112. t.Run("streaming read package: wrong signing key", func(t *testing.T) {
  113. file, err := os.Open(tempFileName)
  114. if err != nil {
  115. t.Fatalf("Open failed: %s", err)
  116. }
  117. defer file.Close()
  118. _, err = NewAuthenticatedDataPackageReader(
  119. file, wrongSigningPublicKey)
  120. if err == nil {
  121. t.Fatalf("NewAuthenticatedDataPackageReader unexpectedly succeeded")
  122. }
  123. })
  124. t.Run("read package: tampered data", func(t *testing.T) {
  125. _, err = ReadAuthenticatedDataPackage(
  126. tamperedPackagePayload, true, signingPublicKey)
  127. if err == nil {
  128. t.Fatalf("ReadAuthenticatedDataPackage unexpectedly succeeded")
  129. }
  130. })
  131. t.Run("streaming read package: tampered data", func(t *testing.T) {
  132. file, err := os.Open(tamperedTempFileName)
  133. if err != nil {
  134. t.Fatalf("Open failed: %s", err)
  135. }
  136. defer file.Close()
  137. _, err = NewAuthenticatedDataPackageReader(
  138. file, signingPublicKey)
  139. if err == nil {
  140. t.Fatalf("NewAuthenticatedDataPackageReader unexpectedly succeeded")
  141. }
  142. })
  143. }
  144. func BenchmarkAuthenticatedPackage(b *testing.B) {
  145. signingPublicKey, signingPrivateKey, err := GenerateAuthenticatedDataPackageKeys()
  146. if err != nil {
  147. b.Fatalf("GenerateAuthenticatedDataPackageKeys failed: %s", err)
  148. }
  149. data := make([]byte, 104857600)
  150. rand.Read(data)
  151. packagePayload, err := WriteAuthenticatedDataPackage(
  152. base64.StdEncoding.EncodeToString(data),
  153. signingPublicKey,
  154. signingPrivateKey)
  155. if err != nil {
  156. b.Fatalf("WriteAuthenticatedDataPackage failed: %s", err)
  157. }
  158. tempFileName, err := makeTempFile(packagePayload)
  159. if err != nil {
  160. b.Fatalf("makeTempFile failed: %s", err)
  161. }
  162. defer os.Remove(tempFileName)
  163. b.Run("read package", func(b *testing.B) {
  164. for i := 0; i < b.N; i++ {
  165. _, err := ReadAuthenticatedDataPackage(
  166. packagePayload, true, signingPublicKey)
  167. if err != nil {
  168. b.Fatalf("ReadAuthenticatedDataPackage failed: %s", err)
  169. }
  170. }
  171. })
  172. b.Run("streaming read package", func(b *testing.B) {
  173. for i := 0; i < b.N; i++ {
  174. file, err := os.Open(tempFileName)
  175. if err != nil {
  176. b.Fatalf("Open failed: %s", err)
  177. }
  178. contentReader, err := NewAuthenticatedDataPackageReader(
  179. file, signingPublicKey)
  180. if err != nil {
  181. file.Close()
  182. b.Fatalf("NewAuthenticatedDataPackageReader failed: %s", err)
  183. }
  184. _, err = io.Copy(ioutil.Discard, contentReader)
  185. if err != nil {
  186. file.Close()
  187. b.Fatalf("Read failed: %s", err)
  188. }
  189. file.Close()
  190. }
  191. })
  192. }
  193. func makeTempFile(data []byte) (string, error) {
  194. file, err := ioutil.TempFile("", "authPackage_test")
  195. if err != nil {
  196. return "", errors.Trace(err)
  197. }
  198. defer file.Close()
  199. _, err = file.Write(data)
  200. if err != nil {
  201. return "", errors.Trace(err)
  202. }
  203. return file.Name(), nil
  204. }