authPackage_test.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  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(CompressionZlib, 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, err := Compress(CompressionZlib, tamperedPackageJSON)
  67. if err != nil {
  68. t.Fatalf("Compress failed: %s", err)
  69. }
  70. tamperedTempFileName, err := makeTempFile(tamperedPackagePayload)
  71. if err != nil {
  72. t.Fatalf("makeTempFile failed: %s", err)
  73. }
  74. defer os.Remove(tempFileName)
  75. t.Run("read package: success", func(t *testing.T) {
  76. content, err := ReadAuthenticatedDataPackage(
  77. packagePayload, true, signingPublicKey)
  78. if err != nil {
  79. t.Fatalf("ReadAuthenticatedDataPackage failed: %s", err)
  80. }
  81. if content != expectedContent {
  82. t.Fatalf(
  83. "unexpected package content: expected %s got %s",
  84. expectedContent, content)
  85. }
  86. })
  87. t.Run("streaming read package: success", func(t *testing.T) {
  88. file, err := os.Open(tempFileName)
  89. if err != nil {
  90. t.Fatalf("Open failed: %s", err)
  91. }
  92. defer file.Close()
  93. contentReader, err := NewAuthenticatedDataPackageReader(
  94. file, signingPublicKey)
  95. if err != nil {
  96. t.Fatalf("NewAuthenticatedDataPackageReader failed: %s", err)
  97. }
  98. content, err := ioutil.ReadAll(contentReader)
  99. if err != nil {
  100. t.Fatalf("ReadAll failed: %s", err)
  101. }
  102. if string(content) != expectedContent {
  103. t.Fatalf(
  104. "unexpected package content: expected %s got %s",
  105. expectedContent, content)
  106. }
  107. })
  108. t.Run("read package: wrong signing key", func(t *testing.T) {
  109. _, err = ReadAuthenticatedDataPackage(
  110. packagePayload, true, wrongSigningPublicKey)
  111. if err == nil {
  112. t.Fatalf("ReadAuthenticatedDataPackage unexpectedly succeeded")
  113. }
  114. })
  115. t.Run("streaming read package: wrong signing key", func(t *testing.T) {
  116. file, err := os.Open(tempFileName)
  117. if err != nil {
  118. t.Fatalf("Open failed: %s", err)
  119. }
  120. defer file.Close()
  121. _, err = NewAuthenticatedDataPackageReader(
  122. file, wrongSigningPublicKey)
  123. if err == nil {
  124. t.Fatalf("NewAuthenticatedDataPackageReader unexpectedly succeeded")
  125. }
  126. })
  127. t.Run("read package: tampered data", func(t *testing.T) {
  128. _, err = ReadAuthenticatedDataPackage(
  129. tamperedPackagePayload, true, signingPublicKey)
  130. if err == nil {
  131. t.Fatalf("ReadAuthenticatedDataPackage unexpectedly succeeded")
  132. }
  133. })
  134. t.Run("streaming read package: tampered data", func(t *testing.T) {
  135. file, err := os.Open(tamperedTempFileName)
  136. if err != nil {
  137. t.Fatalf("Open failed: %s", err)
  138. }
  139. defer file.Close()
  140. _, err = NewAuthenticatedDataPackageReader(
  141. file, signingPublicKey)
  142. if err == nil {
  143. t.Fatalf("NewAuthenticatedDataPackageReader unexpectedly succeeded")
  144. }
  145. })
  146. }
  147. func BenchmarkAuthenticatedPackage(b *testing.B) {
  148. signingPublicKey, signingPrivateKey, err := GenerateAuthenticatedDataPackageKeys()
  149. if err != nil {
  150. b.Fatalf("GenerateAuthenticatedDataPackageKeys failed: %s", err)
  151. }
  152. data := make([]byte, 104857600)
  153. rand.Read(data)
  154. packagePayload, err := WriteAuthenticatedDataPackage(
  155. base64.StdEncoding.EncodeToString(data),
  156. signingPublicKey,
  157. signingPrivateKey)
  158. if err != nil {
  159. b.Fatalf("WriteAuthenticatedDataPackage failed: %s", err)
  160. }
  161. tempFileName, err := makeTempFile(packagePayload)
  162. if err != nil {
  163. b.Fatalf("makeTempFile failed: %s", err)
  164. }
  165. defer os.Remove(tempFileName)
  166. b.Run("read package", func(b *testing.B) {
  167. for i := 0; i < b.N; i++ {
  168. _, err := ReadAuthenticatedDataPackage(
  169. packagePayload, true, signingPublicKey)
  170. if err != nil {
  171. b.Fatalf("ReadAuthenticatedDataPackage failed: %s", err)
  172. }
  173. }
  174. })
  175. b.Run("streaming read package", func(b *testing.B) {
  176. for i := 0; i < b.N; i++ {
  177. file, err := os.Open(tempFileName)
  178. if err != nil {
  179. b.Fatalf("Open failed: %s", err)
  180. }
  181. contentReader, err := NewAuthenticatedDataPackageReader(
  182. file, signingPublicKey)
  183. if err != nil {
  184. file.Close()
  185. b.Fatalf("NewAuthenticatedDataPackageReader failed: %s", err)
  186. }
  187. _, err = io.Copy(ioutil.Discard, contentReader)
  188. if err != nil {
  189. file.Close()
  190. b.Fatalf("Read failed: %s", err)
  191. }
  192. file.Close()
  193. }
  194. })
  195. }
  196. func makeTempFile(data []byte) (string, error) {
  197. file, err := ioutil.TempFile("", "authPackage_test")
  198. if err != nil {
  199. return "", errors.Trace(err)
  200. }
  201. defer file.Close()
  202. _, err = file.Write(data)
  203. if err != nil {
  204. return "", errors.Trace(err)
  205. }
  206. return file.Name(), nil
  207. }