clearsign_test.go 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. // Copyright 2012 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 clearsign
  5. import (
  6. "bytes"
  7. "fmt"
  8. "testing"
  9. "golang.org/x/crypto/openpgp"
  10. "golang.org/x/crypto/openpgp/packet"
  11. )
  12. func testParse(t *testing.T, input []byte, expected, expectedPlaintext string) {
  13. b, rest := Decode(input)
  14. if b == nil {
  15. t.Fatal("failed to decode clearsign message")
  16. }
  17. if !bytes.Equal(rest, []byte("trailing")) {
  18. t.Errorf("unexpected remaining bytes returned: %s", string(rest))
  19. }
  20. if b.ArmoredSignature.Type != "PGP SIGNATURE" {
  21. t.Errorf("bad armor type, got:%s, want:PGP SIGNATURE", b.ArmoredSignature.Type)
  22. }
  23. if !bytes.Equal(b.Bytes, []byte(expected)) {
  24. t.Errorf("bad body, got:%x want:%x", b.Bytes, expected)
  25. }
  26. if !bytes.Equal(b.Plaintext, []byte(expectedPlaintext)) {
  27. t.Errorf("bad plaintext, got:%x want:%x", b.Plaintext, expectedPlaintext)
  28. }
  29. keyring, err := openpgp.ReadArmoredKeyRing(bytes.NewBufferString(signingKey))
  30. if err != nil {
  31. t.Errorf("failed to parse public key: %s", err)
  32. }
  33. if _, err := openpgp.CheckDetachedSignature(keyring, bytes.NewBuffer(b.Bytes), b.ArmoredSignature.Body); err != nil {
  34. t.Errorf("failed to check signature: %s", err)
  35. }
  36. }
  37. func TestParse(t *testing.T) {
  38. testParse(t, clearsignInput, "Hello world\r\nline 2", "Hello world\nline 2\n")
  39. testParse(t, clearsignInput2, "\r\n\r\n(This message has a couple of blank lines at the start and end.)\r\n\r\n", "\n\n(This message has a couple of blank lines at the start and end.)\n\n\n")
  40. }
  41. func TestParseWithNoNewlineAtEnd(t *testing.T) {
  42. input := clearsignInput
  43. input = input[:len(input)-len("trailing")-1]
  44. b, rest := Decode(input)
  45. if b == nil {
  46. t.Fatal("failed to decode clearsign message")
  47. }
  48. if len(rest) > 0 {
  49. t.Errorf("unexpected remaining bytes returned: %s", string(rest))
  50. }
  51. }
  52. var signingTests = []struct {
  53. in, signed, plaintext string
  54. }{
  55. {"", "", ""},
  56. {"a", "a", "a\n"},
  57. {"a\n", "a", "a\n"},
  58. {"-a\n", "-a", "-a\n"},
  59. {"--a\nb", "--a\r\nb", "--a\nb\n"},
  60. // leading whitespace
  61. {" a\n", " a", " a\n"},
  62. {" a\n", " a", " a\n"},
  63. // trailing whitespace (should be stripped)
  64. {"a \n", "a", "a\n"},
  65. {"a ", "a", "a\n"},
  66. // whitespace-only lines (should be stripped)
  67. {" \n", "", "\n"},
  68. {" ", "", "\n"},
  69. {"a\n \n \nb\n", "a\r\n\r\n\r\nb", "a\n\n\nb\n"},
  70. }
  71. func TestSigning(t *testing.T) {
  72. keyring, err := openpgp.ReadArmoredKeyRing(bytes.NewBufferString(signingKey))
  73. if err != nil {
  74. t.Errorf("failed to parse public key: %s", err)
  75. }
  76. for i, test := range signingTests {
  77. var buf bytes.Buffer
  78. plaintext, err := Encode(&buf, keyring[0].PrivateKey, nil)
  79. if err != nil {
  80. t.Errorf("#%d: error from Encode: %s", i, err)
  81. continue
  82. }
  83. if _, err := plaintext.Write([]byte(test.in)); err != nil {
  84. t.Errorf("#%d: error from Write: %s", i, err)
  85. continue
  86. }
  87. if err := plaintext.Close(); err != nil {
  88. t.Fatalf("#%d: error from Close: %s", i, err)
  89. continue
  90. }
  91. b, _ := Decode(buf.Bytes())
  92. if b == nil {
  93. t.Errorf("#%d: failed to decode clearsign message", i)
  94. continue
  95. }
  96. if !bytes.Equal(b.Bytes, []byte(test.signed)) {
  97. t.Errorf("#%d: bad result, got:%x, want:%x", i, b.Bytes, test.signed)
  98. continue
  99. }
  100. if !bytes.Equal(b.Plaintext, []byte(test.plaintext)) {
  101. t.Errorf("#%d: bad result, got:%x, want:%x", i, b.Plaintext, test.plaintext)
  102. continue
  103. }
  104. if _, err := openpgp.CheckDetachedSignature(keyring, bytes.NewBuffer(b.Bytes), b.ArmoredSignature.Body); err != nil {
  105. t.Errorf("#%d: failed to check signature: %s", i, err)
  106. }
  107. }
  108. }
  109. // We use this to make test keys, so that they aren't all the same.
  110. type quickRand byte
  111. func (qr *quickRand) Read(p []byte) (int, error) {
  112. for i := range p {
  113. p[i] = byte(*qr)
  114. }
  115. *qr++
  116. return len(p), nil
  117. }
  118. func TestMultiSign(t *testing.T) {
  119. if testing.Short() {
  120. t.Skip("skipping long test in -short mode")
  121. }
  122. zero := quickRand(0)
  123. config := packet.Config{Rand: &zero}
  124. for nKeys := 0; nKeys < 4; nKeys++ {
  125. nextTest:
  126. for nExtra := 0; nExtra < 4; nExtra++ {
  127. var signKeys []*packet.PrivateKey
  128. var verifyKeys openpgp.EntityList
  129. desc := fmt.Sprintf("%d keys; %d of which will be used to verify", nKeys+nExtra, nKeys)
  130. for i := 0; i < nKeys+nExtra; i++ {
  131. e, err := openpgp.NewEntity("name", "comment", "email", &config)
  132. if err != nil {
  133. t.Errorf("cannot create key: %v", err)
  134. continue nextTest
  135. }
  136. if i < nKeys {
  137. verifyKeys = append(verifyKeys, e)
  138. }
  139. signKeys = append(signKeys, e.PrivateKey)
  140. }
  141. input := []byte("this is random text\r\n4 17")
  142. var output bytes.Buffer
  143. w, err := EncodeMulti(&output, signKeys, nil)
  144. if err != nil {
  145. t.Errorf("EncodeMulti (%s) failed: %v", desc, err)
  146. }
  147. if _, err := w.Write(input); err != nil {
  148. t.Errorf("Write(%q) to signer (%s) failed: %v", string(input), desc, err)
  149. }
  150. if err := w.Close(); err != nil {
  151. t.Errorf("Close() of signer (%s) failed: %v", desc, err)
  152. }
  153. block, _ := Decode(output.Bytes())
  154. if string(block.Bytes) != string(input) {
  155. t.Errorf("Inline data didn't match original; got %q want %q", string(block.Bytes), string(input))
  156. }
  157. _, err = openpgp.CheckDetachedSignature(verifyKeys, bytes.NewReader(block.Bytes), block.ArmoredSignature.Body)
  158. if nKeys == 0 {
  159. if err == nil {
  160. t.Errorf("verifying inline (%s) succeeded; want failure", desc)
  161. }
  162. } else {
  163. if err != nil {
  164. t.Errorf("verifying inline (%s) failed (%v); want success", desc, err)
  165. }
  166. }
  167. }
  168. }
  169. }
  170. const signatureBlock = `
  171. -----BEGIN PGP SIGNATURE-----
  172. Version: OpenPrivacy 0.99
  173. yDgBO22WxBHv7O8X7O/jygAEzol56iUKiXmV+XmpCtmpqQUKiQrFqclFqUDBovzS
  174. vBSFjNSiVHsuAA==
  175. =njUN
  176. -----END PGP SIGNATURE-----
  177. `
  178. var invalidInputs = []string{
  179. `
  180. -----BEGIN PGP SIGNED MESSAGE-----
  181. Hash: SHA256
  182. (This message was truncated.)
  183. `,
  184. `
  185. -----BEGIN PGP SIGNED MESSAGE-----garbage
  186. Hash: SHA256
  187. _o/
  188. ` + signatureBlock,
  189. `
  190. garbage-----BEGIN PGP SIGNED MESSAGE-----
  191. Hash: SHA256
  192. _o/
  193. ` + signatureBlock,
  194. `
  195. -----BEGIN PGP SIGNED MESSAGE-----
  196. Hash: SHA` + "\x0b\x0b" + `256
  197. _o/
  198. ` + signatureBlock,
  199. `
  200. -----BEGIN PGP SIGNED MESSAGE-----
  201. NotHash: SHA256
  202. _o/
  203. ` + signatureBlock,
  204. }
  205. func TestParseInvalid(t *testing.T) {
  206. for i, input := range invalidInputs {
  207. if b, rest := Decode([]byte(input)); b != nil {
  208. t.Errorf("#%d: decoded a bad clearsigned message without any error", i)
  209. } else if string(rest) != input {
  210. t.Errorf("#%d: did not return all data with a bad message", i)
  211. }
  212. }
  213. }
  214. var clearsignInput = []byte(`
  215. ;lasjlkfdsa
  216. -----BEGIN PGP SIGNED MESSAGE-----
  217. Hash: SHA1
  218. Hello world
  219. line 2
  220. -----BEGIN PGP SIGNATURE-----
  221. Version: GnuPG v1.4.10 (GNU/Linux)
  222. iJwEAQECAAYFAk8kMuEACgkQO9o98PRieSpMsAQAhmY/vwmNpflrPgmfWsYhk5O8
  223. pjnBUzZwqTDoDeINjZEoPDSpQAHGhjFjgaDx/Gj4fAl0dM4D0wuUEBb6QOrwflog
  224. 2A2k9kfSOMOtk0IH/H5VuFN1Mie9L/erYXjTQIptv9t9J7NoRBMU0QOOaFU0JaO9
  225. MyTpno24AjIAGb+mH1U=
  226. =hIJ6
  227. -----END PGP SIGNATURE-----
  228. trailing`)
  229. var clearsignInput2 = []byte(`
  230. asdlfkjasdlkfjsadf
  231. -----BEGIN PGP SIGNED MESSAGE-----
  232. Hash: SHA256
  233. (This message has a couple of blank lines at the start and end.)
  234. -----BEGIN PGP SIGNATURE-----
  235. Version: GnuPG v1.4.11 (GNU/Linux)
  236. iJwEAQEIAAYFAlPpSREACgkQO9o98PRieSpZTAP+M8QUoCt/7Rf3YbXPcdzIL32v
  237. pt1I+cMNeopzfLy0u4ioEFi8s5VkwpL1AFmirvgViCwlf82inoRxzZRiW05JQ5LI
  238. ESEzeCoy2LIdRCQ2hcrG8pIUPzUO4TqO5D/dMbdHwNH4h5nNmGJUAEG6FpURlPm+
  239. qZg6BaTvOxepqOxnhVU=
  240. =e+C6
  241. -----END PGP SIGNATURE-----
  242. trailing`)
  243. var signingKey = `-----BEGIN PGP PRIVATE KEY BLOCK-----
  244. Version: GnuPG v1.4.10 (GNU/Linux)
  245. lQHYBE2rFNoBBADFwqWQIW/DSqcB4yCQqnAFTJ27qS5AnB46ccAdw3u4Greeu3Bp
  246. idpoHdjULy7zSKlwR1EA873dO/k/e11Ml3dlAFUinWeejWaK2ugFP6JjiieSsrKn
  247. vWNicdCS4HTWn0X4sjl0ZiAygw6GNhqEQ3cpLeL0g8E9hnYzJKQ0LWJa0QARAQAB
  248. AAP/TB81EIo2VYNmTq0pK1ZXwUpxCrvAAIG3hwKjEzHcbQznsjNvPUihZ+NZQ6+X
  249. 0HCfPAdPkGDCLCb6NavcSW+iNnLTrdDnSI6+3BbIONqWWdRDYJhqZCkqmG6zqSfL
  250. IdkJgCw94taUg5BWP/AAeQrhzjChvpMQTVKQL5mnuZbUCeMCAN5qrYMP2S9iKdnk
  251. VANIFj7656ARKt/nf4CBzxcpHTyB8+d2CtPDKCmlJP6vL8t58Jmih+kHJMvC0dzn
  252. gr5f5+sCAOOe5gt9e0am7AvQWhdbHVfJU0TQJx+m2OiCJAqGTB1nvtBLHdJnfdC9
  253. TnXXQ6ZXibqLyBies/xeY2sCKL5qtTMCAKnX9+9d/5yQxRyrQUHt1NYhaXZnJbHx
  254. q4ytu0eWz+5i68IYUSK69jJ1NWPM0T6SkqpB3KCAIv68VFm9PxqG1KmhSrQIVGVz
  255. dCBLZXmIuAQTAQIAIgUCTasU2gIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AA
  256. CgkQO9o98PRieSoLhgQAkLEZex02Qt7vGhZzMwuN0R22w3VwyYyjBx+fM3JFETy1
  257. ut4xcLJoJfIaF5ZS38UplgakHG0FQ+b49i8dMij0aZmDqGxrew1m4kBfjXw9B/v+
  258. eIqpODryb6cOSwyQFH0lQkXC040pjq9YqDsO5w0WYNXYKDnzRV0p4H1pweo2VDid
  259. AdgETasU2gEEAN46UPeWRqKHvA99arOxee38fBt2CI08iiWyI8T3J6ivtFGixSqV
  260. bRcPxYO/qLpVe5l84Nb3X71GfVXlc9hyv7CD6tcowL59hg1E/DC5ydI8K8iEpUmK
  261. /UnHdIY5h8/kqgGxkY/T/hgp5fRQgW1ZoZxLajVlMRZ8W4tFtT0DeA+JABEBAAEA
  262. A/0bE1jaaZKj6ndqcw86jd+QtD1SF+Cf21CWRNeLKnUds4FRRvclzTyUMuWPkUeX
  263. TaNNsUOFqBsf6QQ2oHUBBK4VCHffHCW4ZEX2cd6umz7mpHW6XzN4DECEzOVksXtc
  264. lUC1j4UB91DC/RNQqwX1IV2QLSwssVotPMPqhOi0ZLNY7wIA3n7DWKInxYZZ4K+6
  265. rQ+POsz6brEoRHwr8x6XlHenq1Oki855pSa1yXIARoTrSJkBtn5oI+f8AzrnN0BN
  266. oyeQAwIA/7E++3HDi5aweWrViiul9cd3rcsS0dEnksPhvS0ozCJiHsq/6GFmy7J8
  267. QSHZPteedBnZyNp5jR+H7cIfVN3KgwH/Skq4PsuPhDq5TKK6i8Pc1WW8MA6DXTdU
  268. nLkX7RGmMwjC0DBf7KWAlPjFaONAX3a8ndnz//fy1q7u2l9AZwrj1qa1iJ8EGAEC
  269. AAkFAk2rFNoCGwwACgkQO9o98PRieSo2/QP/WTzr4ioINVsvN1akKuekmEMI3LAp
  270. BfHwatufxxP1U+3Si/6YIk7kuPB9Hs+pRqCXzbvPRrI8NHZBmc8qIGthishdCYad
  271. AHcVnXjtxrULkQFGbGvhKURLvS9WnzD/m1K2zzwxzkPTzT9/Yf06O6Mal5AdugPL
  272. VrM0m72/jnpKo04=
  273. =zNCn
  274. -----END PGP PRIVATE KEY BLOCK-----
  275. `