浏览代码

Update go-git

父节点
当前提交
b99ae88b1d
签署人:: Brendan Abolivier <contact@brendanabolivier.com> GPG 密钥 ID: 8EF1500759F70623
共有 100 个文件被更改,包括 13935 次插入2 次删除
  1. 34
    2
      vendor/manifest
  2. 2
    0
      vendor/src/github.com/kevinburke/ssh_config/AUTHORS.txt
  3. 49
    0
      vendor/src/github.com/kevinburke/ssh_config/LICENSE
  4. 29
    0
      vendor/src/github.com/kevinburke/ssh_config/Makefile
  5. 81
    0
      vendor/src/github.com/kevinburke/ssh_config/README.md
  6. 639
    0
      vendor/src/github.com/kevinburke/ssh_config/config.go
  7. 340
    0
      vendor/src/github.com/kevinburke/ssh_config/config_test.go
  8. 48
    0
      vendor/src/github.com/kevinburke/ssh_config/example_test.go
  9. 235
    0
      vendor/src/github.com/kevinburke/ssh_config/lexer.go
  10. 182
    0
      vendor/src/github.com/kevinburke/ssh_config/parser.go
  11. 25
    0
      vendor/src/github.com/kevinburke/ssh_config/position.go
  12. 3
    0
      vendor/src/github.com/kevinburke/ssh_config/testdata/anotherfile
  13. 39
    0
      vendor/src/github.com/kevinburke/ssh_config/testdata/config1
  14. 50
    0
      vendor/src/github.com/kevinburke/ssh_config/testdata/config2
  15. 31
    0
      vendor/src/github.com/kevinburke/ssh_config/testdata/config3
  16. 4
    0
      vendor/src/github.com/kevinburke/ssh_config/testdata/config4
  17. 4
    0
      vendor/src/github.com/kevinburke/ssh_config/testdata/eqsign
  18. 2
    0
      vendor/src/github.com/kevinburke/ssh_config/testdata/extraspace
  19. 4
    0
      vendor/src/github.com/kevinburke/ssh_config/testdata/include
  20. 4
    0
      vendor/src/github.com/kevinburke/ssh_config/testdata/include-recursive
  21. 2
    0
      vendor/src/github.com/kevinburke/ssh_config/testdata/invalid-port
  22. 2
    0
      vendor/src/github.com/kevinburke/ssh_config/testdata/match-directive
  23. 5
    0
      vendor/src/github.com/kevinburke/ssh_config/testdata/negated
  24. 0
    0
      vendor/src/github.com/kevinburke/ssh_config/testdata/system-include
  25. 49
    0
      vendor/src/github.com/kevinburke/ssh_config/token.go
  26. 162
    0
      vendor/src/github.com/kevinburke/ssh_config/validators.go
  27. 44
    0
      vendor/src/github.com/kevinburke/ssh_config/validators_test.go
  28. 61
    0
      vendor/src/github.com/pelletier/go-buffruneio/README.md
  29. 133
    0
      vendor/src/github.com/pelletier/go-buffruneio/buffruneio.go
  30. 264
    0
      vendor/src/github.com/pelletier/go-buffruneio/buffruneio_test.go
  31. 526
    0
      vendor/src/golang.org/x/crypto/cast5/cast5.go
  32. 106
    0
      vendor/src/golang.org/x/crypto/cast5/cast5_test.go
  33. 219
    0
      vendor/src/golang.org/x/crypto/openpgp/armor/armor.go
  34. 95
    0
      vendor/src/golang.org/x/crypto/openpgp/armor/armor_test.go
  35. 160
    0
      vendor/src/golang.org/x/crypto/openpgp/armor/encode.go
  36. 59
    0
      vendor/src/golang.org/x/crypto/openpgp/canonical_text.go
  37. 52
    0
      vendor/src/golang.org/x/crypto/openpgp/canonical_text_test.go
  38. 376
    0
      vendor/src/golang.org/x/crypto/openpgp/clearsign/clearsign.go
  39. 210
    0
      vendor/src/golang.org/x/crypto/openpgp/clearsign/clearsign_test.go
  40. 122
    0
      vendor/src/golang.org/x/crypto/openpgp/elgamal/elgamal.go
  41. 49
    0
      vendor/src/golang.org/x/crypto/openpgp/elgamal/elgamal_test.go
  42. 72
    0
      vendor/src/golang.org/x/crypto/openpgp/errors/errors.go
  43. 636
    0
      vendor/src/golang.org/x/crypto/openpgp/keys.go
  44. 419
    0
      vendor/src/golang.org/x/crypto/openpgp/keys_test.go
  45. 123
    0
      vendor/src/golang.org/x/crypto/openpgp/packet/compressed.go
  46. 41
    0
      vendor/src/golang.org/x/crypto/openpgp/packet/compressed_test.go
  47. 91
    0
      vendor/src/golang.org/x/crypto/openpgp/packet/config.go
  48. 199
    0
      vendor/src/golang.org/x/crypto/openpgp/packet/encrypted_key.go
  49. 146
    0
      vendor/src/golang.org/x/crypto/openpgp/packet/encrypted_key_test.go
  50. 89
    0
      vendor/src/golang.org/x/crypto/openpgp/packet/literal.go
  51. 143
    0
      vendor/src/golang.org/x/crypto/openpgp/packet/ocfb.go
  52. 46
    0
      vendor/src/golang.org/x/crypto/openpgp/packet/ocfb_test.go
  53. 73
    0
      vendor/src/golang.org/x/crypto/openpgp/packet/one_pass_signature.go
  54. 162
    0
      vendor/src/golang.org/x/crypto/openpgp/packet/opaque.go
  55. 67
    0
      vendor/src/golang.org/x/crypto/openpgp/packet/opaque_test.go
  56. 537
    0
      vendor/src/golang.org/x/crypto/openpgp/packet/packet.go
  57. 255
    0
      vendor/src/golang.org/x/crypto/openpgp/packet/packet_test.go
  58. 380
    0
      vendor/src/golang.org/x/crypto/openpgp/packet/private_key.go
  59. 270
    0
      vendor/src/golang.org/x/crypto/openpgp/packet/private_key_test.go
  60. 748
    0
      vendor/src/golang.org/x/crypto/openpgp/packet/public_key.go
  61. 202
    0
      vendor/src/golang.org/x/crypto/openpgp/packet/public_key_test.go
  62. 279
    0
      vendor/src/golang.org/x/crypto/openpgp/packet/public_key_v3.go
  63. 82
    0
      vendor/src/golang.org/x/crypto/openpgp/packet/public_key_v3_test.go
  64. 76
    0
      vendor/src/golang.org/x/crypto/openpgp/packet/reader.go
  65. 731
    0
      vendor/src/golang.org/x/crypto/openpgp/packet/signature.go
  66. 78
    0
      vendor/src/golang.org/x/crypto/openpgp/packet/signature_test.go
  67. 146
    0
      vendor/src/golang.org/x/crypto/openpgp/packet/signature_v3.go
  68. 92
    0
      vendor/src/golang.org/x/crypto/openpgp/packet/signature_v3_test.go
  69. 155
    0
      vendor/src/golang.org/x/crypto/openpgp/packet/symmetric_key_encrypted.go
  70. 117
    0
      vendor/src/golang.org/x/crypto/openpgp/packet/symmetric_key_encrypted_test.go
  71. 290
    0
      vendor/src/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted.go
  72. 123
    0
      vendor/src/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted_test.go
  73. 91
    0
      vendor/src/golang.org/x/crypto/openpgp/packet/userattribute.go
  74. 109
    0
      vendor/src/golang.org/x/crypto/openpgp/packet/userattribute_test.go
  75. 160
    0
      vendor/src/golang.org/x/crypto/openpgp/packet/userid.go
  76. 87
    0
      vendor/src/golang.org/x/crypto/openpgp/packet/userid_test.go
  77. 442
    0
      vendor/src/golang.org/x/crypto/openpgp/read.go
  78. 613
    0
      vendor/src/golang.org/x/crypto/openpgp/read_test.go
  79. 273
    0
      vendor/src/golang.org/x/crypto/openpgp/s2k/s2k.go
  80. 137
    0
      vendor/src/golang.org/x/crypto/openpgp/s2k/s2k_test.go
  81. 378
    0
      vendor/src/golang.org/x/crypto/openpgp/write.go
  82. 273
    0
      vendor/src/golang.org/x/crypto/openpgp/write_test.go
  83. 3
    0
      vendor/src/gopkg.in/src-d/go-git-fixtures.v3/README.md
  84. 二进制
      vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/git-0a00a25543e6d732dbf4e8e9fec55c8e65fc4e8d.tgz
  85. 二进制
      vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/git-174be6bd4292c18160542ae6dc6704b877b8a01a.tgz
  86. 二进制
      vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/git-21504f6d2cc2ef0c9d6ebb8802c7b49abae40c1a.tgz
  87. 二进制
      vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/git-4870d54b5b04e43da8cf99ceec179d9675494af8.tgz
  88. 二进制
      vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/git-4e7600af05c3356e8b142263e127b76f010facfc.tgz
  89. 二进制
      vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/git-78c5fb882e76286d8201016cffee63ea7060a0c2.tgz
  90. 二进制
      vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/git-7a725350b88b05ca03541b59dd0649fda7f521f2.tgz
  91. 二进制
      vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/git-7cbde0ca02f13aedd5ec8b358ca17b1c0bf5ee64.tgz
  92. 二进制
      vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/git-935e5ac17c41c309c356639816ea0694a568c484.tgz
  93. 二进制
      vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/git-bf3fedcc8e20fd0dec9172987ceea0038d17b516.tgz
  94. 二进制
      vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/git-c0c7c57ab1753ddbd26cc45322299ddd12842794.tgz
  95. 二进制
      vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/git-df6781fd40b8f4911d70ce71f8387b991615cd6d.tgz
  96. 二进制
      vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/git-e1580a78f7d36791249df76df8a2a2613d629902.tgz
  97. 二进制
      vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/pack-0d3d824fb5c930e7e7e1f0f399f2976847d31fd3.idx
  98. 二进制
      vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/pack-0d3d824fb5c930e7e7e1f0f399f2976847d31fd3.pack
  99. 二进制
      vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/pack-0d9b6cfc261785837939aaede5986d7a7c212518.idx
  100. 0
    0
      vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/pack-0d9b6cfc261785837939aaede5986d7a7c212518.pack

+ 34
- 2
vendor/manifest 查看文件

@@ -27,12 +27,24 @@
27 27
 			"branch": "master"
28 28
 		},
29 29
 		{
30
+			"importpath": "github.com/kevinburke/ssh_config",
31
+			"repository": "https://github.com/kevinburke/ssh_config",
32
+			"revision": "0ff8514904a8ebfcfb3c32ad73e1f8498a7f81b4",
33
+			"branch": "master"
34
+		},
35
+		{
30 36
 			"importpath": "github.com/mitchellh/go-homedir",
31 37
 			"repository": "https://github.com/mitchellh/go-homedir",
32 38
 			"revision": "b8bc1bf767474819792c23f32d8286a45736f1c6",
33 39
 			"branch": "master"
34 40
 		},
35 41
 		{
42
+			"importpath": "github.com/pelletier/go-buffruneio",
43
+			"repository": "https://github.com/pelletier/go-buffruneio",
44
+			"revision": "e2f66f8164ca709d4c21e815860afd2024e9b894",
45
+			"branch": "master"
46
+		},
47
+		{
36 48
 			"importpath": "github.com/rainycape/unidecode",
37 49
 			"repository": "https://github.com/rainycape/unidecode",
38 50
 			"revision": "cb7f23ec59bec0d61b19c56cd88cee3d0cc1870c",
@@ -70,6 +82,13 @@
70 82
 			"branch": "master"
71 83
 		},
72 84
 		{
85
+			"importpath": "golang.org/x/crypto/cast5",
86
+			"repository": "https://go.googlesource.com/crypto",
87
+			"revision": "1875d0a70c90e57f11972aefd42276df65e895b9",
88
+			"branch": "master",
89
+			"path": "/cast5"
90
+		},
91
+		{
73 92
 			"importpath": "golang.org/x/crypto/curve25519",
74 93
 			"repository": "https://go.googlesource.com/crypto",
75 94
 			"revision": "0fcca4842a8d74bfddc2c96a073bd2a4d2a7a2e8",
@@ -84,6 +103,13 @@
84 103
 			"path": "/ed25519"
85 104
 		},
86 105
 		{
106
+			"importpath": "golang.org/x/crypto/openpgp",
107
+			"repository": "https://go.googlesource.com/crypto",
108
+			"revision": "1875d0a70c90e57f11972aefd42276df65e895b9",
109
+			"branch": "master",
110
+			"path": "/openpgp"
111
+		},
112
+		{
87 113
 			"importpath": "golang.org/x/crypto/ssh",
88 114
 			"repository": "https://go.googlesource.com/crypto",
89 115
 			"revision": "0fcca4842a8d74bfddc2c96a073bd2a4d2a7a2e8",
@@ -143,10 +169,16 @@
143 169
 			"branch": "master"
144 170
 		},
145 171
 		{
172
+			"importpath": "gopkg.in/src-d/go-git-fixtures.v3",
173
+			"repository": "https://gopkg.in/src-d/go-git-fixtures.v3",
174
+			"revision": "a29d269c3be65e4d1b20c29133c74e0551e1aa5d",
175
+			"branch": "master"
176
+		},
177
+		{
146 178
 			"importpath": "gopkg.in/src-d/go-git.v4",
147 179
 			"repository": "https://gopkg.in/src-d/go-git.v4",
148
-			"revision": "f9879dd043f84936a1f8acb8a53b74332a7ae135",
149
-			"branch": "v4"
180
+			"revision": "e9247ce9c5ce12126f646ca3ddf0066e4829bd14",
181
+			"branch": "master"
150 182
 		},
151 183
 		{
152 184
 			"importpath": "gopkg.in/warnings.v0",

+ 2
- 0
vendor/src/github.com/kevinburke/ssh_config/AUTHORS.txt 查看文件

@@ -0,0 +1,2 @@
1
+Kevin Burke <kev@inburke.com>
2
+Sergey Lukjanov <me@slukjanov.name>

+ 49
- 0
vendor/src/github.com/kevinburke/ssh_config/LICENSE 查看文件

@@ -0,0 +1,49 @@
1
+Copyright (c) 2017 Kevin Burke.
2
+
3
+Permission is hereby granted, free of charge, to any person
4
+obtaining a copy of this software and associated documentation
5
+files (the "Software"), to deal in the Software without
6
+restriction, including without limitation the rights to use,
7
+copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+copies of the Software, and to permit persons to whom the
9
+Software is furnished to do so, subject to the following
10
+conditions:
11
+
12
+The above copyright notice and this permission notice shall be
13
+included in all copies or substantial portions of the Software.
14
+
15
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+===================
25
+
26
+The lexer and parser borrow heavily from github.com/pelletier/go-toml. The
27
+license for that project is copied below.
28
+
29
+The MIT License (MIT)
30
+
31
+Copyright (c) 2013 - 2017 Thomas Pelletier, Eric Anderton
32
+
33
+Permission is hereby granted, free of charge, to any person obtaining a copy
34
+of this software and associated documentation files (the "Software"), to deal
35
+in the Software without restriction, including without limitation the rights
36
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
37
+copies of the Software, and to permit persons to whom the Software is
38
+furnished to do so, subject to the following conditions:
39
+
40
+The above copyright notice and this permission notice shall be included in all
41
+copies or substantial portions of the Software.
42
+
43
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
44
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
45
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
46
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
47
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
48
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
49
+SOFTWARE.

+ 29
- 0
vendor/src/github.com/kevinburke/ssh_config/Makefile 查看文件

@@ -0,0 +1,29 @@
1
+BUMP_VERSION := $(GOPATH)/bin/bump_version
2
+MEGACHECK := $(GOPATH)/bin/megacheck
3
+WRITE_MAILMAP := $(GOPATH)/bin/write_mailmap
4
+
5
+IGNORES := 'github.com/kevinburke/ssh_config/config.go:U1000 github.com/kevinburke/ssh_config/config.go:S1002 github.com/kevinburke/ssh_config/token.go:U1000'
6
+
7
+$(MEGACHECK):
8
+	go get honnef.co/go/tools/cmd/megacheck
9
+
10
+lint: $(MEGACHECK)
11
+	go vet ./...
12
+	$(MEGACHECK) --ignore=$(IGNORES) ./...
13
+
14
+test: lint
15
+	@# the timeout helps guard against infinite recursion
16
+	go test -timeout=50ms ./...
17
+
18
+$(BUMP_VERSION):
19
+	go get github.com/Shyp/bump_version
20
+
21
+release: $(BUMP_VERSION)
22
+	$(BUMP_VERSION) minor config.go
23
+
24
+force: ;
25
+
26
+AUTHORS.txt: force | $(WRITE_MAILMAP)
27
+	$(WRITE_MAILMAP) > AUTHORS.txt
28
+
29
+authors: AUTHORS.txt

+ 81
- 0
vendor/src/github.com/kevinburke/ssh_config/README.md 查看文件

@@ -0,0 +1,81 @@
1
+# ssh_config
2
+
3
+This is a Go parser for `ssh_config` files. Importantly, this parser attempts
4
+to preserve comments in a given file, so you can manipulate a `ssh_config` file
5
+from a program, if your heart desires.
6
+
7
+It's designed to be used with the excellent
8
+[x/crypto/ssh](https://golang.org/x/crypto/ssh) package, which handles SSH
9
+negotiation but isn't very easy to configure.
10
+
11
+The `ssh_config` `Get()` and `GetStrict()` functions will attempt to read values
12
+from `$HOME/.ssh/config` and fall back to `/etc/ssh/ssh_config`. The first
13
+argument is the host name to match on, and the second argument is the key you
14
+want to retrieve.
15
+
16
+```go
17
+port := ssh_config.Get("myhost", "Port")
18
+```
19
+
20
+You can also load a config file and read values from it.
21
+
22
+```go
23
+var config = `
24
+Host *.test
25
+  Compression yes
26
+`
27
+
28
+cfg, err := ssh_config.Decode(strings.NewReader(config))
29
+fmt.Println(cfg.Get("example.test", "Port"))
30
+```
31
+
32
+Some SSH arguments have default values - for example, the default value for
33
+`KeyboardAuthentication` is `"yes"`. If you call Get(), and no value for the
34
+given Host/keyword pair exists in the config, we'll return a default for the
35
+keyword if one exists.
36
+
37
+### Manipulating SSH config files
38
+
39
+Here's how you can manipulate an SSH config file, and then write it back to
40
+disk.
41
+
42
+```go
43
+f, _ := os.Open(filepath.Join(os.Getenv("HOME"), ".ssh", "config"))
44
+cfg, _ := ssh_config.Decode(f)
45
+for _, host := range cfg.Hosts {
46
+    fmt.Println("patterns:", host.Patterns)
47
+    for _, node := range host.Nodes {
48
+        // Manipulate the nodes as you see fit, or use a type switch to
49
+        // distinguish between Empty, KV, and Include nodes.
50
+        fmt.Println(node.String())
51
+    }
52
+}
53
+
54
+// Print the config to stdout:
55
+fmt.Println(cfg.String())
56
+```
57
+
58
+## Spec compliance
59
+
60
+Wherever possible we try to implement the specification as documented in
61
+the `ssh_config` manpage. Unimplemented features should be present in the
62
+[issues][issues] list.
63
+
64
+Notably, the `Match` directive is currently unsupported.
65
+
66
+[issues]: https://github.com/kevinburke/ssh_config/issues
67
+
68
+## Errata
69
+
70
+This is the second [comment-preserving configuration parser][blog] I've written, after
71
+[an /etc/hosts parser][hostsfile]. Eventually, I will write one for every Linux
72
+file format.
73
+
74
+[blog]: https://kev.inburke.com/kevin/more-comment-preserving-configuration-parsers/
75
+[hostsfile]: https://github.com/kevinburke/hostsfile
76
+
77
+## Donating
78
+
79
+Donations free up time to make improvements to the library, and respond to
80
+bug reports. You can send donations via Paypal's "Send Money" feature to
81
+kev@inburke.com. Donations are not tax deductible in the USA.

+ 639
- 0
vendor/src/github.com/kevinburke/ssh_config/config.go 查看文件

@@ -0,0 +1,639 @@
1
+// Package ssh_config provides tools for manipulating SSH config files.
2
+//
3
+// Importantly, this parser attempts to preserve comments in a given file, so
4
+// you can manipulate a `ssh_config` file from a program, if your heart desires.
5
+//
6
+// The Get() and GetStrict() functions will attempt to read values from
7
+// $HOME/.ssh/config, falling back to /etc/ssh/ssh_config. The first argument is
8
+// the host name to match on ("example.com"), and the second argument is the key
9
+// you want to retrieve ("Port"). The keywords are case insensitive.
10
+//
11
+// 		port := ssh_config.Get("myhost", "Port")
12
+//
13
+// You can also manipulate an SSH config file and then print it or write it back
14
+// to disk.
15
+//
16
+//	f, _ := os.Open(filepath.Join(os.Getenv("HOME"), ".ssh", "config"))
17
+//	cfg, _ := ssh_config.Decode(f)
18
+//	for _, host := range cfg.Hosts {
19
+//		fmt.Println("patterns:", host.Patterns)
20
+//		for _, node := range host.Nodes {
21
+//			fmt.Println(node.String())
22
+//		}
23
+//	}
24
+//
25
+//	// Write the cfg back to disk:
26
+//	fmt.Println(cfg.String())
27
+//
28
+// BUG: the Match directive is currently unsupported; parsing a config with
29
+// a Match directive will trigger an error.
30
+package ssh_config
31
+
32
+import (
33
+	"bytes"
34
+	"errors"
35
+	"fmt"
36
+	"io"
37
+	"os"
38
+	osuser "os/user"
39
+	"path/filepath"
40
+	"regexp"
41
+	"runtime"
42
+	"strings"
43
+	"sync"
44
+)
45
+
46
+const version = "0.3"
47
+
48
+type configFinder func() string
49
+
50
+// UserSettings checks ~/.ssh and /etc/ssh for configuration files. The config
51
+// files are parsed and cached the first time Get() or GetStrict() is called.
52
+type UserSettings struct {
53
+	IgnoreErrors       bool
54
+	systemConfig       *Config
55
+	systemConfigFinder configFinder
56
+	userConfig         *Config
57
+	userConfigFinder   configFinder
58
+	loadConfigs        sync.Once
59
+	onceErr            error
60
+}
61
+
62
+func homedir() string {
63
+	user, err := osuser.Current()
64
+	if err == nil {
65
+		return user.HomeDir
66
+	} else {
67
+		return os.Getenv("HOME")
68
+	}
69
+}
70
+
71
+func userConfigFinder() string {
72
+	return filepath.Join(homedir(), ".ssh", "config")
73
+}
74
+
75
+// DefaultUserSettings is the default UserSettings and is used by Get and
76
+// GetStrict. It checks both $HOME/.ssh/config and /etc/ssh/ssh_config for keys,
77
+// and it will return parse errors (if any) instead of swallowing them.
78
+var DefaultUserSettings = &UserSettings{
79
+	IgnoreErrors:       false,
80
+	systemConfigFinder: systemConfigFinder,
81
+	userConfigFinder:   userConfigFinder,
82
+}
83
+
84
+func systemConfigFinder() string {
85
+	return filepath.Join("/", "etc", "ssh", "ssh_config")
86
+}
87
+
88
+func findVal(c *Config, alias, key string) (string, error) {
89
+	if c == nil {
90
+		return "", nil
91
+	}
92
+	val, err := c.Get(alias, key)
93
+	if err != nil || val == "" {
94
+		return "", err
95
+	}
96
+	if err := validate(key, val); err != nil {
97
+		return "", err
98
+	}
99
+	return val, nil
100
+}
101
+
102
+// Get finds the first value for key within a declaration that matches the
103
+// alias. Get returns the empty string if no value was found, or if IgnoreErrors
104
+// is false and we could not parse the configuration file. Use GetStrict to
105
+// disambiguate the latter cases.
106
+//
107
+// The match for key is case insensitive.
108
+//
109
+// Get is a wrapper around DefaultUserSettings.Get.
110
+func Get(alias, key string) string {
111
+	return DefaultUserSettings.Get(alias, key)
112
+}
113
+
114
+// GetStrict finds the first value for key within a declaration that matches the
115
+// alias. If key has a default value and no matching configuration is found, the
116
+// default will be returned. For more information on default values and the way
117
+// patterns are matched, see the manpage for ssh_config.
118
+//
119
+// error will be non-nil if and only if a user's configuration file or the
120
+// system configuration file could not be parsed, and u.IgnoreErrors is false.
121
+//
122
+// GetStrict is a wrapper around DefaultUserSettings.GetStrict.
123
+func GetStrict(alias, key string) (string, error) {
124
+	return DefaultUserSettings.GetStrict(alias, key)
125
+}
126
+
127
+// Get finds the first value for key within a declaration that matches the
128
+// alias. Get returns the empty string if no value was found, or if IgnoreErrors
129
+// is false and we could not parse the configuration file. Use GetStrict to
130
+// disambiguate the latter cases.
131
+//
132
+// The match for key is case insensitive.
133
+func (u *UserSettings) Get(alias, key string) string {
134
+	val, err := u.GetStrict(alias, key)
135
+	if err != nil {
136
+		return ""
137
+	}
138
+	return val
139
+}
140
+
141
+// GetStrict finds the first value for key within a declaration that matches the
142
+// alias. If key has a default value and no matching configuration is found, the
143
+// default will be returned. For more information on default values and the way
144
+// patterns are matched, see the manpage for ssh_config.
145
+//
146
+// error will be non-nil if and only if a user's configuration file or the
147
+// system configuration file could not be parsed, and u.IgnoreErrors is false.
148
+func (u *UserSettings) GetStrict(alias, key string) (string, error) {
149
+	u.loadConfigs.Do(func() {
150
+		// can't parse user file, that's ok.
151
+		var filename string
152
+		if u.userConfigFinder == nil {
153
+			filename = userConfigFinder()
154
+		} else {
155
+			filename = u.userConfigFinder()
156
+		}
157
+		var err error
158
+		u.userConfig, err = parseFile(filename)
159
+		if err != nil && os.IsNotExist(err) == false {
160
+			u.onceErr = err
161
+			return
162
+		}
163
+		if u.systemConfigFinder == nil {
164
+			filename = systemConfigFinder()
165
+		} else {
166
+			filename = u.systemConfigFinder()
167
+		}
168
+		u.systemConfig, err = parseFile(filename)
169
+		if err != nil && os.IsNotExist(err) == false {
170
+			u.onceErr = err
171
+			return
172
+		}
173
+	})
174
+	if u.onceErr != nil && u.IgnoreErrors == false {
175
+		return "", u.onceErr
176
+	}
177
+	val, err := findVal(u.userConfig, alias, key)
178
+	if err != nil || val != "" {
179
+		return val, err
180
+	}
181
+	val2, err2 := findVal(u.systemConfig, alias, key)
182
+	if err2 != nil || val2 != "" {
183
+		return val2, err2
184
+	}
185
+	return Default(key), nil
186
+}
187
+
188
+func parseFile(filename string) (*Config, error) {
189
+	return parseWithDepth(filename, 0)
190
+}
191
+
192
+func parseWithDepth(filename string, depth uint8) (*Config, error) {
193
+	f, err := os.Open(filename)
194
+	if err != nil {
195
+		return nil, err
196
+	}
197
+	defer f.Close()
198
+	return decode(f, isSystem(filename), depth)
199
+}
200
+
201
+func isSystem(filename string) bool {
202
+	// TODO i'm not sure this is the best way to detect a system repo
203
+	return strings.HasPrefix(filepath.Clean(filename), "/etc/ssh")
204
+}
205
+
206
+// Decode reads r into a Config, or returns an error if r could not be parsed as
207
+// an SSH config file.
208
+func Decode(r io.Reader) (*Config, error) {
209
+	return decode(r, false, 0)
210
+}
211
+
212
+func decode(r io.Reader, system bool, depth uint8) (c *Config, err error) {
213
+	defer func() {
214
+		if r := recover(); r != nil {
215
+			if _, ok := r.(runtime.Error); ok {
216
+				panic(r)
217
+			}
218
+			if e, ok := r.(error); ok && e == ErrDepthExceeded {
219
+				err = e
220
+				return
221
+			}
222
+			err = errors.New(r.(string))
223
+		}
224
+	}()
225
+
226
+	c = parseSSH(lexSSH(r), system, depth)
227
+	return c, err
228
+}
229
+
230
+// Config represents an SSH config file.
231
+type Config struct {
232
+	// A list of hosts to match against. The file begins with an implicit
233
+	// "Host *" declaration matching all hosts.
234
+	Hosts    []*Host
235
+	depth    uint8
236
+	position Position
237
+}
238
+
239
+// Get finds the first value in the configuration that matches the alias and
240
+// contains key. Get returns the empty string if no value was found, or if the
241
+// Config contains an invalid conditional Include value.
242
+//
243
+// The match for key is case insensitive.
244
+func (c *Config) Get(alias, key string) (string, error) {
245
+	lowerKey := strings.ToLower(key)
246
+	for _, host := range c.Hosts {
247
+		if !host.Matches(alias) {
248
+			continue
249
+		}
250
+		for _, node := range host.Nodes {
251
+			switch t := node.(type) {
252
+			case *Empty:
253
+				continue
254
+			case *KV:
255
+				// "keys are case insensitive" per the spec
256
+				lkey := strings.ToLower(t.Key)
257
+				if lkey == "match" {
258
+					panic("can't handle Match directives")
259
+				}
260
+				if lkey == lowerKey {
261
+					return t.Value, nil
262
+				}
263
+			case *Include:
264
+				val := t.Get(alias, key)
265
+				if val != "" {
266
+					return val, nil
267
+				}
268
+			default:
269
+				return "", fmt.Errorf("unknown Node type %v", t)
270
+			}
271
+		}
272
+	}
273
+	return "", nil
274
+}
275
+
276
+// String returns a string representation of the Config file.
277
+func (c Config) String() string {
278
+	return marshal(c).String()
279
+}
280
+
281
+func (c Config) MarshalText() ([]byte, error) {
282
+	return marshal(c).Bytes(), nil
283
+}
284
+
285
+func marshal(c Config) *bytes.Buffer {
286
+	var buf bytes.Buffer
287
+	for i := range c.Hosts {
288
+		buf.WriteString(c.Hosts[i].String())
289
+	}
290
+	return &buf
291
+}
292
+
293
+// Pattern is a pattern in a Host declaration. Patterns are read-only values;
294
+// create a new one with NewPattern().
295
+type Pattern struct {
296
+	str   string // Its appearance in the file, not the value that gets compiled.
297
+	regex *regexp.Regexp
298
+	not   bool // True if this is a negated match
299
+}
300
+
301
+// String prints the string representation of the pattern.
302
+func (p Pattern) String() string {
303
+	return p.str
304
+}
305
+
306
+// Copied from regexp.go with * and ? removed.
307
+var specialBytes = []byte(`\.+()|[]{}^$`)
308
+
309
+func special(b byte) bool {
310
+	return bytes.IndexByte(specialBytes, b) >= 0
311
+}
312
+
313
+// NewPattern creates a new Pattern for matching hosts. NewPattern("*") creates
314
+// a Pattern that matches all hosts.
315
+//
316
+// From the manpage, a pattern consists of zero or more non-whitespace
317
+// characters, `*' (a wildcard that matches zero or more characters), or `?' (a
318
+// wildcard that matches exactly one character). For example, to specify a set
319
+// of declarations for any host in the ".co.uk" set of domains, the following
320
+// pattern could be used:
321
+//
322
+//	Host *.co.uk
323
+//
324
+// The following pattern would match any host in the 192.168.0.[0-9] network range:
325
+//
326
+//	Host 192.168.0.?
327
+func NewPattern(s string) (*Pattern, error) {
328
+	if s == "" {
329
+		return nil, errors.New("ssh_config: empty pattern")
330
+	}
331
+	negated := false
332
+	if s[0] == '!' {
333
+		negated = true
334
+		s = s[1:]
335
+	}
336
+	var buf bytes.Buffer
337
+	buf.WriteByte('^')
338
+	for i := 0; i < len(s); i++ {
339
+		// A byte loop is correct because all metacharacters are ASCII.
340
+		switch b := s[i]; b {
341
+		case '*':
342
+			buf.WriteString(".*")
343
+		case '?':
344
+			buf.WriteString(".?")
345
+		default:
346
+			// borrowing from QuoteMeta here.
347
+			if special(b) {
348
+				buf.WriteByte('\\')
349
+			}
350
+			buf.WriteByte(b)
351
+		}
352
+	}
353
+	buf.WriteByte('$')
354
+	r, err := regexp.Compile(buf.String())
355
+	if err != nil {
356
+		return nil, err
357
+	}
358
+	return &Pattern{str: s, regex: r, not: negated}, nil
359
+}
360
+
361
+// Host describes a Host directive and the keywords that follow it.
362
+type Host struct {
363
+	// A list of host patterns that should match this host.
364
+	Patterns []*Pattern
365
+	// A Node is either a key/value pair or a comment line.
366
+	Nodes []Node
367
+	// EOLComment is the comment (if any) terminating the Host line.
368
+	EOLComment   string
369
+	hasEquals    bool
370
+	leadingSpace uint16 // TODO: handle spaces vs tabs here.
371
+	// The file starts with an implicit "Host *" declaration.
372
+	implicit bool
373
+}
374
+
375
+// Matches returns true if the Host matches for the given alias. For
376
+// a description of the rules that provide a match, see the manpage for
377
+// ssh_config.
378
+func (h *Host) Matches(alias string) bool {
379
+	found := false
380
+	for i := range h.Patterns {
381
+		if h.Patterns[i].regex.MatchString(alias) {
382
+			if h.Patterns[i].not == true {
383
+				// Negated match. "A pattern entry may be negated by prefixing
384
+				// it with an exclamation mark (`!'). If a negated entry is
385
+				// matched, then the Host entry is ignored, regardless of
386
+				// whether any other patterns on the line match. Negated matches
387
+				// are therefore useful to provide exceptions for wildcard
388
+				// matches."
389
+				return false
390
+			}
391
+			found = true
392
+		}
393
+	}
394
+	return found
395
+}
396
+
397
+// String prints h as it would appear in a config file. Minor tweaks may be
398
+// present in the whitespace in the printed file.
399
+func (h *Host) String() string {
400
+	var buf bytes.Buffer
401
+	if h.implicit == false {
402
+		buf.WriteString(strings.Repeat(" ", int(h.leadingSpace)))
403
+		buf.WriteString("Host")
404
+		if h.hasEquals {
405
+			buf.WriteString(" = ")
406
+		} else {
407
+			buf.WriteString(" ")
408
+		}
409
+		for i, pat := range h.Patterns {
410
+			buf.WriteString(pat.String())
411
+			if i < len(h.Patterns)-1 {
412
+				buf.WriteString(" ")
413
+			}
414
+		}
415
+		if h.EOLComment != "" {
416
+			buf.WriteString(" #")
417
+			buf.WriteString(h.EOLComment)
418
+		}
419
+		buf.WriteByte('\n')
420
+	}
421
+	for i := range h.Nodes {
422
+		buf.WriteString(h.Nodes[i].String())
423
+		buf.WriteByte('\n')
424
+	}
425
+	return buf.String()
426
+}
427
+
428
+// Node represents a line in a Config.
429
+type Node interface {
430
+	Pos() Position
431
+	String() string
432
+}
433
+
434
+// KV is a line in the config file that contains a key, a value, and possibly
435
+// a comment.
436
+type KV struct {
437
+	Key          string
438
+	Value        string
439
+	Comment      string
440
+	hasEquals    bool
441
+	leadingSpace uint16 // Space before the key. TODO handle spaces vs tabs.
442
+	position     Position
443
+}
444
+
445
+// Pos returns k's Position.
446
+func (k *KV) Pos() Position {
447
+	return k.position
448
+}
449
+
450
+// String prints k as it was parsed in the config file. There may be slight
451
+// changes to the whitespace between values.
452
+func (k *KV) String() string {
453
+	if k == nil {
454
+		return ""
455
+	}
456
+	equals := " "
457
+	if k.hasEquals {
458
+		equals = " = "
459
+	}
460
+	line := fmt.Sprintf("%s%s%s%s", strings.Repeat(" ", int(k.leadingSpace)), k.Key, equals, k.Value)
461
+	if k.Comment != "" {
462
+		line += " #" + k.Comment
463
+	}
464
+	return line
465
+}
466
+
467
+// Empty is a line in the config file that contains only whitespace or comments.
468
+type Empty struct {
469
+	Comment      string
470
+	leadingSpace uint16 // TODO handle spaces vs tabs.
471
+	position     Position
472
+}
473
+
474
+// Pos returns e's Position.
475
+func (e *Empty) Pos() Position {
476
+	return e.position
477
+}
478
+
479
+// String prints e as it was parsed in the config file.
480
+func (e *Empty) String() string {
481
+	if e == nil {
482
+		return ""
483
+	}
484
+	if e.Comment == "" {
485
+		return ""
486
+	}
487
+	return fmt.Sprintf("%s#%s", strings.Repeat(" ", int(e.leadingSpace)), e.Comment)
488
+}
489
+
490
+// Include holds the result of an Include directive, including the config files
491
+// that have been parsed as part of that directive. At most 5 levels of Include
492
+// statements will be parsed.
493
+type Include struct {
494
+	// Comment is the contents of any comment at the end of the Include
495
+	// statement.
496
+	Comment string
497
+	parsed  bool
498
+	// an include directive can include several different files, and wildcards
499
+	directives []string
500
+
501
+	mu sync.Mutex
502
+	// 1:1 mapping between matches and keys in files array; matches preserves
503
+	// ordering
504
+	matches []string
505
+	// actual filenames are listed here
506
+	files        map[string]*Config
507
+	leadingSpace uint16
508
+	position     Position
509
+	depth        uint8
510
+	hasEquals    bool
511
+}
512
+
513
+const maxRecurseDepth = 5
514
+
515
+// ErrDepthExceeded is returned if too many Include directives are parsed.
516
+// Usually this indicates a recursive loop (an Include directive pointing to the
517
+// file it contains).
518
+var ErrDepthExceeded = errors.New("ssh_config: max recurse depth exceeded")
519
+
520
+func removeDups(arr []string) []string {
521
+	// Use map to record duplicates as we find them.
522
+	encountered := make(map[string]bool, len(arr))
523
+	result := make([]string, 0)
524
+
525
+	for v := range arr {
526
+		if encountered[arr[v]] == false {
527
+			encountered[arr[v]] = true
528
+			result = append(result, arr[v])
529
+		}
530
+	}
531
+	return result
532
+}
533
+
534
+// NewInclude creates a new Include with a list of file globs to include.
535
+// Configuration files are parsed greedily (e.g. as soon as this function runs).
536
+// Any error encountered while parsing nested configuration files will be
537
+// returned.
538
+func NewInclude(directives []string, hasEquals bool, pos Position, comment string, system bool, depth uint8) (*Include, error) {
539
+	if depth > maxRecurseDepth {
540
+		return nil, ErrDepthExceeded
541
+	}
542
+	inc := &Include{
543
+		Comment:      comment,
544
+		directives:   directives,
545
+		files:        make(map[string]*Config),
546
+		position:     pos,
547
+		leadingSpace: uint16(pos.Col) - 1,
548
+		depth:        depth,
549
+		hasEquals:    hasEquals,
550
+	}
551
+	// no need for inc.mu.Lock() since nothing else can access this inc
552
+	matches := make([]string, 0)
553
+	for i := range directives {
554
+		var path string
555
+		if filepath.IsAbs(directives[i]) {
556
+			path = directives[i]
557
+		} else if system {
558
+			path = filepath.Join("/etc/ssh", directives[i])
559
+		} else {
560
+			path = filepath.Join(homedir(), ".ssh", directives[i])
561
+		}
562
+		theseMatches, err := filepath.Glob(path)
563
+		if err != nil {
564
+			return nil, err
565
+		}
566
+		matches = append(matches, theseMatches...)
567
+	}
568
+	matches = removeDups(matches)
569
+	inc.matches = matches
570
+	for i := range matches {
571
+		config, err := parseWithDepth(matches[i], depth)
572
+		if err != nil {
573
+			return nil, err
574
+		}
575
+		inc.files[matches[i]] = config
576
+	}
577
+	return inc, nil
578
+}
579
+
580
+// Pos returns the position of the Include directive in the larger file.
581
+func (i *Include) Pos() Position {
582
+	return i.position
583
+}
584
+
585
+// Get finds the first value in the Include statement matching the alias and the
586
+// given key.
587
+func (inc *Include) Get(alias, key string) string {
588
+	inc.mu.Lock()
589
+	defer inc.mu.Unlock()
590
+	// TODO: we search files in any order which is not correct
591
+	for i := range inc.matches {
592
+		cfg := inc.files[inc.matches[i]]
593
+		if cfg == nil {
594
+			panic("nil cfg")
595
+		}
596
+		val, err := cfg.Get(alias, key)
597
+		if err == nil && val != "" {
598
+			return val
599
+		}
600
+	}
601
+	return ""
602
+}
603
+
604
+// String prints out a string representation of this Include directive. Note
605
+// included Config files are not printed as part of this representation.
606
+func (inc *Include) String() string {
607
+	equals := " "
608
+	if inc.hasEquals {
609
+		equals = " = "
610
+	}
611
+	line := fmt.Sprintf("%sInclude%s%s", strings.Repeat(" ", int(inc.leadingSpace)), equals, strings.Join(inc.directives, " "))
612
+	if inc.Comment != "" {
613
+		line += " #" + inc.Comment
614
+	}
615
+	return line
616
+}
617
+
618
+var matchAll *Pattern
619
+
620
+func init() {
621
+	var err error
622
+	matchAll, err = NewPattern("*")
623
+	if err != nil {
624
+		panic(err)
625
+	}
626
+}
627
+
628
+func newConfig() *Config {
629
+	return &Config{
630
+		Hosts: []*Host{
631
+			&Host{
632
+				implicit: true,
633
+				Patterns: []*Pattern{matchAll},
634
+				Nodes:    make([]Node, 0),
635
+			},
636
+		},
637
+		depth: 0,
638
+	}
639
+}

+ 340
- 0
vendor/src/github.com/kevinburke/ssh_config/config_test.go 查看文件

@@ -0,0 +1,340 @@
1
+package ssh_config
2
+
3
+import (
4
+	"bytes"
5
+	"io/ioutil"
6
+	"log"
7
+	"os"
8
+	"path/filepath"
9
+	"strings"
10
+	"testing"
11
+)
12
+
13
+func loadFile(t *testing.T, filename string) []byte {
14
+	data, err := ioutil.ReadFile(filename)
15
+	if err != nil {
16
+		t.Fatal(err)
17
+	}
18
+	return data
19
+}
20
+
21
+var files = []string{"testdata/config1", "testdata/config2"}
22
+
23
+func TestDecode(t *testing.T) {
24
+	for _, filename := range files {
25
+		data := loadFile(t, filename)
26
+		cfg, err := Decode(bytes.NewReader(data))
27
+		if err != nil {
28
+			t.Fatal(err)
29
+		}
30
+		out := cfg.String()
31
+		if out != string(data) {
32
+			t.Errorf("out != data: out: %q\ndata: %q", out, string(data))
33
+		}
34
+	}
35
+}
36
+
37
+func testConfigFinder(filename string) func() string {
38
+	return func() string { return filename }
39
+}
40
+
41
+func nullConfigFinder() string {
42
+	return ""
43
+}
44
+
45
+func TestGet(t *testing.T) {
46
+	us := &UserSettings{
47
+		userConfigFinder: testConfigFinder("testdata/config1"),
48
+	}
49
+
50
+	val := us.Get("wap", "User")
51
+	if val != "root" {
52
+		t.Errorf("expected to find User root, got %q", val)
53
+	}
54
+}
55
+
56
+func TestGetWithDefault(t *testing.T) {
57
+	us := &UserSettings{
58
+		userConfigFinder: testConfigFinder("testdata/config1"),
59
+	}
60
+
61
+	val, err := us.GetStrict("wap", "PasswordAuthentication")
62
+	if err != nil {
63
+		t.Fatalf("expected nil err, got %v", err)
64
+	}
65
+	if val != "yes" {
66
+		t.Errorf("expected to get PasswordAuthentication yes, got %q", val)
67
+	}
68
+}
69
+
70
+func TestGetInvalidPort(t *testing.T) {
71
+	us := &UserSettings{
72
+		userConfigFinder: testConfigFinder("testdata/invalid-port"),
73
+	}
74
+
75
+	val, err := us.GetStrict("test.test", "Port")
76
+	if err == nil {
77
+		t.Fatalf("expected non-nil err, got nil")
78
+	}
79
+	if val != "" {
80
+		t.Errorf("expected to get '' for val, got %q", val)
81
+	}
82
+	if err.Error() != `ssh_config: strconv.ParseUint: parsing "notanumber": invalid syntax` {
83
+		t.Errorf("wrong error: got %v", err)
84
+	}
85
+}
86
+
87
+func TestGetNotFoundNoDefault(t *testing.T) {
88
+	us := &UserSettings{
89
+		userConfigFinder: testConfigFinder("testdata/config1"),
90
+	}
91
+
92
+	val, err := us.GetStrict("wap", "CanonicalDomains")
93
+	if err != nil {
94
+		t.Fatalf("expected nil err, got %v", err)
95
+	}
96
+	if val != "" {
97
+		t.Errorf("expected to get CanonicalDomains '', got %q", val)
98
+	}
99
+}
100
+
101
+func TestGetWildcard(t *testing.T) {
102
+	us := &UserSettings{
103
+		userConfigFinder: testConfigFinder("testdata/config3"),
104
+	}
105
+
106
+	val := us.Get("bastion.stage.i.us.example.net", "Port")
107
+	if val != "22" {
108
+		t.Errorf("expected to find Port 22, got %q", val)
109
+	}
110
+
111
+	val = us.Get("bastion.net", "Port")
112
+	if val != "25" {
113
+		t.Errorf("expected to find Port 24, got %q", val)
114
+	}
115
+
116
+	val = us.Get("10.2.3.4", "Port")
117
+	if val != "23" {
118
+		t.Errorf("expected to find Port 23, got %q", val)
119
+	}
120
+	val = us.Get("101.2.3.4", "Port")
121
+	if val != "25" {
122
+		t.Errorf("expected to find Port 24, got %q", val)
123
+	}
124
+	val = us.Get("20.20.20.4", "Port")
125
+	if val != "24" {
126
+		t.Errorf("expected to find Port 24, got %q", val)
127
+	}
128
+	val = us.Get("20.20.20.20", "Port")
129
+	if val != "25" {
130
+		t.Errorf("expected to find Port 25, got %q", val)
131
+	}
132
+}
133
+
134
+func TestGetExtraSpaces(t *testing.T) {
135
+	us := &UserSettings{
136
+		userConfigFinder: testConfigFinder("testdata/extraspace"),
137
+	}
138
+
139
+	val := us.Get("test.test", "Port")
140
+	if val != "1234" {
141
+		t.Errorf("expected to find Port 1234, got %q", val)
142
+	}
143
+}
144
+
145
+func TestGetCaseInsensitive(t *testing.T) {
146
+	us := &UserSettings{
147
+		userConfigFinder: testConfigFinder("testdata/config1"),
148
+	}
149
+
150
+	val := us.Get("wap", "uSER")
151
+	if val != "root" {
152
+		t.Errorf("expected to find User root, got %q", val)
153
+	}
154
+}
155
+
156
+func TestGetEmpty(t *testing.T) {
157
+	us := &UserSettings{
158
+		userConfigFinder:   nullConfigFinder,
159
+		systemConfigFinder: nullConfigFinder,
160
+	}
161
+	val, err := us.GetStrict("wap", "User")
162
+	if err != nil {
163
+		t.Errorf("expected nil error, got %v", err)
164
+	}
165
+	if val != "" {
166
+		t.Errorf("expected to get empty string, got %q", val)
167
+	}
168
+}
169
+
170
+func TestGetEqsign(t *testing.T) {
171
+	us := &UserSettings{
172
+		userConfigFinder: testConfigFinder("testdata/eqsign"),
173
+	}
174
+
175
+	val := us.Get("test.test", "Port")
176
+	if val != "1234" {
177
+		t.Errorf("expected to find Port 1234, got %q", val)
178
+	}
179
+	val = us.Get("test.test", "Port2")
180
+	if val != "5678" {
181
+		t.Errorf("expected to find Port2 5678, got %q", val)
182
+	}
183
+}
184
+
185
+var includeFile = []byte(`
186
+# This host should not exist, so we can use it for test purposes / it won't
187
+# interfere with any other configurations.
188
+Host kevinburke.ssh_config.test.example.com
189
+    Port 4567
190
+`)
191
+
192
+func TestInclude(t *testing.T) {
193
+	if testing.Short() {
194
+		t.Skip("skipping fs write in short mode")
195
+	}
196
+	testPath := filepath.Join(homedir(), ".ssh", "kevinburke-ssh-config-test-file")
197
+	err := ioutil.WriteFile(testPath, includeFile, 0644)
198
+	if err != nil {
199
+		t.Skipf("couldn't write SSH config file: %v", err.Error())
200
+	}
201
+	defer os.Remove(testPath)
202
+	us := &UserSettings{
203
+		userConfigFinder: testConfigFinder("testdata/include"),
204
+	}
205
+	val := us.Get("kevinburke.ssh_config.test.example.com", "Port")
206
+	if val != "4567" {
207
+		t.Errorf("expected to find Port=4567 in included file, got %q", val)
208
+	}
209
+}
210
+
211
+func TestIncludeSystem(t *testing.T) {
212
+	if testing.Short() {
213
+		t.Skip("skipping fs write in short mode")
214
+	}
215
+	testPath := filepath.Join("/", "etc", "ssh", "kevinburke-ssh-config-test-file")
216
+	err := ioutil.WriteFile(testPath, includeFile, 0644)
217
+	if err != nil {
218
+		t.Skipf("couldn't write SSH config file: %v", err.Error())
219
+	}
220
+	defer os.Remove(testPath)
221
+	us := &UserSettings{
222
+		systemConfigFinder: testConfigFinder("testdata/include"),
223
+	}
224
+	val := us.Get("kevinburke.ssh_config.test.example.com", "Port")
225
+	if val != "4567" {
226
+		t.Errorf("expected to find Port=4567 in included file, got %q", val)
227
+	}
228
+}
229
+
230
+var recursiveIncludeFile = []byte(`
231
+Host kevinburke.ssh_config.test.example.com
232
+	Include kevinburke-ssh-config-recursive-include
233
+`)
234
+
235
+func TestIncludeRecursive(t *testing.T) {
236
+	if testing.Short() {
237
+		t.Skip("skipping fs write in short mode")
238
+	}
239
+	testPath := filepath.Join(homedir(), ".ssh", "kevinburke-ssh-config-recursive-include")
240
+	err := ioutil.WriteFile(testPath, recursiveIncludeFile, 0644)
241
+	if err != nil {
242
+		t.Skipf("couldn't write SSH config file: %v", err.Error())
243
+	}
244
+	defer os.Remove(testPath)
245
+	us := &UserSettings{
246
+		userConfigFinder: testConfigFinder("testdata/include-recursive"),
247
+	}
248
+	val, err := us.GetStrict("kevinburke.ssh_config.test.example.com", "Port")
249
+	if err != ErrDepthExceeded {
250
+		t.Errorf("Recursive include: expected ErrDepthExceeded, got %v", err)
251
+	}
252
+	if val != "" {
253
+		t.Errorf("non-empty string value %s", val)
254
+	}
255
+}
256
+
257
+func TestIncludeString(t *testing.T) {
258
+	if testing.Short() {
259
+		t.Skip("skipping fs write in short mode")
260
+	}
261
+	data, err := ioutil.ReadFile("testdata/include")
262
+	if err != nil {
263
+		log.Fatal(err)
264
+	}
265
+	c, err := Decode(bytes.NewReader(data))
266
+	if err != nil {
267
+		t.Fatal(err)
268
+	}
269
+	s := c.String()
270
+	if s != string(data) {
271
+		t.Errorf("mismatch: got %q\nwant %q", s, string(data))
272
+	}
273
+}
274
+
275
+var matchTests = []struct {
276
+	in    []string
277
+	alias string
278
+	want  bool
279
+}{
280
+	{[]string{"*"}, "any.test", true},
281
+	{[]string{"a", "b", "*", "c"}, "any.test", true},
282
+	{[]string{"a", "b", "c"}, "any.test", false},
283
+	{[]string{"any.test"}, "any1test", false},
284
+	{[]string{"192.168.0.?"}, "192.168.0.1", true},
285
+	{[]string{"192.168.0.?"}, "192.168.0.10", false},
286
+	{[]string{"*.co.uk"}, "bbc.co.uk", true},
287
+	{[]string{"*.co.uk"}, "subdomain.bbc.co.uk", true},
288
+	{[]string{"*.*.co.uk"}, "bbc.co.uk", false},
289
+	{[]string{"*.*.co.uk"}, "subdomain.bbc.co.uk", true},
290
+	{[]string{"*.example.com", "!*.dialup.example.com", "foo.dialup.example.com"}, "foo.dialup.example.com", false},
291
+	{[]string{"test.*", "!test.host"}, "test.host", false},
292
+}
293
+
294
+func TestMatches(t *testing.T) {
295
+	for _, tt := range matchTests {
296
+		patterns := make([]*Pattern, len(tt.in))
297
+		for i := range tt.in {
298
+			pat, err := NewPattern(tt.in[i])
299
+			if err != nil {
300
+				t.Fatalf("error compiling pattern %s: %v", tt.in[i], err)
301
+			}
302
+			patterns[i] = pat
303
+		}
304
+		host := &Host{
305
+			Patterns: patterns,
306
+		}
307
+		got := host.Matches(tt.alias)
308
+		if got != tt.want {
309
+			t.Errorf("host(%q).Matches(%q): got %v, want %v", tt.in, tt.alias, got, tt.want)
310
+		}
311
+	}
312
+}
313
+
314
+func TestMatchUnsupported(t *testing.T) {
315
+	us := &UserSettings{
316
+		userConfigFinder: testConfigFinder("testdata/match-directive"),
317
+	}
318
+
319
+	_, err := us.GetStrict("test.test", "Port")
320
+	if err == nil {
321
+		t.Fatal("expected Match directive to error, didn't")
322
+	}
323
+	if !strings.Contains(err.Error(), "ssh_config: Match directive parsing is unsupported") {
324
+		t.Errorf("wrong error: %v", err)
325
+	}
326
+}
327
+
328
+func TestIndexInRange(t *testing.T) {
329
+	us := &UserSettings{
330
+		userConfigFinder: testConfigFinder("testdata/config4"),
331
+	}
332
+
333
+	user, err := us.GetStrict("wap", "User")
334
+	if err != nil {
335
+		t.Fatal(err)
336
+	}
337
+	if user != "root" {
338
+		t.Errorf("expected User to be %q, got %q", "root", user)
339
+	}
340
+}

+ 48
- 0
vendor/src/github.com/kevinburke/ssh_config/example_test.go 查看文件

@@ -0,0 +1,48 @@
1
+package ssh_config_test
2
+
3
+import (
4
+	"fmt"
5
+	"strings"
6
+
7
+	"github.com/kevinburke/ssh_config"
8
+)
9
+
10
+func ExampleHost_Matches() {
11
+	pat, _ := ssh_config.NewPattern("test.*.example.com")
12
+	host := &ssh_config.Host{Patterns: []*ssh_config.Pattern{pat}}
13
+	fmt.Println(host.Matches("test.stage.example.com"))
14
+	fmt.Println(host.Matches("othersubdomain.example.com"))
15
+	// Output:
16
+	// true
17
+	// false
18
+}
19
+
20
+func ExamplePattern() {
21
+	pat, _ := ssh_config.NewPattern("*")
22
+	host := &ssh_config.Host{Patterns: []*ssh_config.Pattern{pat}}
23
+	fmt.Println(host.Matches("test.stage.example.com"))
24
+	fmt.Println(host.Matches("othersubdomain.any.any"))
25
+	// Output:
26
+	// true
27
+	// true
28
+}
29
+
30
+func ExampleDecode() {
31
+	var config = `
32
+Host *.example.com
33
+  Compression yes
34
+`
35
+
36
+	cfg, _ := ssh_config.Decode(strings.NewReader(config))
37
+	val, _ := cfg.Get("test.example.com", "Compression")
38
+	fmt.Println(val)
39
+	// Output: yes
40
+}
41
+
42
+func ExampleDefault() {
43
+	fmt.Println(ssh_config.Default("Port"))
44
+	fmt.Println(ssh_config.Default("UnknownVar"))
45
+	// Output:
46
+	// 22
47
+	//
48
+}

+ 235
- 0
vendor/src/github.com/kevinburke/ssh_config/lexer.go 查看文件

@@ -0,0 +1,235 @@
1
+package ssh_config
2
+
3
+import (
4
+	"io"
5
+
6
+	buffruneio "github.com/pelletier/go-buffruneio"
7
+)
8
+
9
+// Define state functions
10
+type sshLexStateFn func() sshLexStateFn
11
+
12
+type sshLexer struct {
13
+	input         *buffruneio.Reader // Textual source
14
+	buffer        []rune             // Runes composing the current token
15
+	tokens        chan token
16
+	line          uint32
17
+	col           uint16
18
+	endbufferLine uint32
19
+	endbufferCol  uint16
20
+}
21
+
22
+func (s *sshLexer) lexComment(previousState sshLexStateFn) sshLexStateFn {
23
+	return func() sshLexStateFn {
24
+		growingString := ""
25
+		for next := s.peek(); next != '\n' && next != eof; next = s.peek() {
26
+			if next == '\r' && s.follow("\r\n") {
27
+				break
28
+			}
29
+			growingString += string(next)
30
+			s.next()
31
+		}
32
+		s.emitWithValue(tokenComment, growingString)
33
+		s.skip()
34
+		return previousState
35
+	}
36
+}
37
+
38
+// lex the space after an equals sign in a function
39
+func (s *sshLexer) lexRspace() sshLexStateFn {
40
+	for {
41
+		next := s.peek()
42
+		if !isSpace(next) {
43
+			break
44
+		}
45
+		s.skip()
46
+	}
47
+	return s.lexRvalue
48
+}
49
+
50
+func (s *sshLexer) lexEquals() sshLexStateFn {
51
+	for {
52
+		next := s.peek()
53
+		if next == '=' {
54
+			s.emit(tokenEquals)
55
+			s.skip()
56
+			return s.lexRspace
57
+		}
58
+		// TODO error handling here; newline eof etc.
59
+		if !isSpace(next) {
60
+			break
61
+		}
62
+		s.skip()
63
+	}
64
+	return s.lexRvalue
65
+}
66
+
67
+func (s *sshLexer) lexKey() sshLexStateFn {
68
+	growingString := ""
69
+
70
+	for r := s.peek(); isKeyChar(r); r = s.peek() {
71
+		// simplified a lot here
72
+		if isSpace(r) || r == '=' {
73
+			s.emitWithValue(tokenKey, growingString)
74
+			s.skip()
75
+			return s.lexEquals
76
+		}
77
+		growingString += string(r)
78
+		s.next()
79
+	}
80
+	s.emitWithValue(tokenKey, growingString)
81
+	return s.lexEquals
82
+}
83
+
84
+func (s *sshLexer) lexRvalue() sshLexStateFn {
85
+	growingString := ""
86
+	for {
87
+		next := s.peek()
88
+		switch next {
89
+		case '\n':
90
+			s.emitWithValue(tokenString, growingString)
91
+			s.skip()
92
+			return s.lexVoid
93
+		case '#':
94
+			s.emitWithValue(tokenString, growingString)
95
+			s.skip()
96
+			return s.lexComment(s.lexVoid)
97
+		case eof:
98
+			s.next()
99
+		}
100
+		if next == eof {
101
+			break
102
+		}
103
+		growingString += string(next)
104
+		s.next()
105
+	}
106
+	s.emit(tokenEOF)
107
+	return nil
108
+}
109
+
110
+func (s *sshLexer) read() rune {
111
+	r, _, err := s.input.ReadRune()
112
+	if err != nil {
113
+		panic(err)
114
+	}
115
+	if r == '\n' {
116
+		s.endbufferLine++
117
+		s.endbufferCol = 1
118
+	} else {
119
+		s.endbufferCol++
120
+	}
121
+	return r
122
+}
123
+
124
+func (s *sshLexer) next() rune {
125
+	r := s.read()
126
+
127
+	if r != eof {
128
+		s.buffer = append(s.buffer, r)
129
+	}
130
+	return r
131
+}
132
+
133
+func (s *sshLexer) lexVoid() sshLexStateFn {
134
+	for {
135
+		next := s.peek()
136
+		switch next {
137
+		case '#':
138
+			s.skip()
139
+			return s.lexComment(s.lexVoid)
140
+		case '\r':
141
+			fallthrough
142
+		case '\n':
143
+			s.emit(tokenEmptyLine)
144
+			s.skip()
145
+			continue
146
+		}
147
+
148
+		if isSpace(next) {
149
+			s.skip()
150
+		}
151
+
152
+		if isKeyStartChar(next) {
153
+			return s.lexKey
154
+		}
155
+
156
+		// removed IsKeyStartChar and lexKey. probably will need to readd
157
+
158
+		if next == eof {
159
+			s.next()
160
+			break
161
+		}
162
+	}
163
+
164
+	s.emit(tokenEOF)
165
+	return nil
166
+}
167
+
168
+func (s *sshLexer) ignore() {
169
+	s.buffer = make([]rune, 0)
170
+	s.line = s.endbufferLine
171
+	s.col = s.endbufferCol
172
+}
173
+
174
+func (s *sshLexer) skip() {
175
+	s.next()
176
+	s.ignore()
177
+}
178
+
179
+func (s *sshLexer) emit(t tokenType) {
180
+	s.emitWithValue(t, string(s.buffer))
181
+}
182
+
183
+func (s *sshLexer) emitWithValue(t tokenType, value string) {
184
+	tok := token{
185
+		Position: Position{s.line, s.col},
186
+		typ:      t,
187
+		val:      value,
188
+	}
189
+	s.tokens <- tok
190
+	s.ignore()
191
+}
192
+
193
+func (s *sshLexer) peek() rune {
194
+	r, _, err := s.input.ReadRune()
195
+	if err != nil {
196
+		panic(err)
197
+	}
198
+	s.input.UnreadRune()
199
+	return r
200
+}
201
+
202
+func (s *sshLexer) follow(next string) bool {
203
+	for _, expectedRune := range next {
204
+		r, _, err := s.input.ReadRune()
205
+		defer s.input.UnreadRune()
206
+		if err != nil {
207
+			panic(err)
208
+		}
209
+		if expectedRune != r {
210
+			return false
211
+		}
212
+	}
213
+	return true
214
+}
215
+
216
+func (s *sshLexer) run() {
217
+	for state := s.lexVoid; state != nil; {
218
+		state = state()
219
+	}
220
+	close(s.tokens)
221
+}
222
+
223
+func lexSSH(input io.Reader) chan token {
224
+	bufferedInput := buffruneio.NewReader(input)
225
+	l := &sshLexer{
226
+		input:         bufferedInput,
227
+		tokens:        make(chan token),
228
+		line:          1,
229
+		col:           1,
230
+		endbufferLine: 1,
231
+		endbufferCol:  1,
232
+	}
233
+	go l.run()
234
+	return l.tokens
235
+}

+ 182
- 0
vendor/src/github.com/kevinburke/ssh_config/parser.go 查看文件

@@ -0,0 +1,182 @@
1
+package ssh_config
2
+
3
+import (
4
+	"fmt"
5
+	"strings"
6
+)
7
+
8
+type sshParser struct {
9
+	flow          chan token
10
+	config        *Config
11
+	tokensBuffer  []token
12
+	currentTable  []string
13
+	seenTableKeys []string
14
+	// /etc/ssh parser or local parser - used to find the default for relative
15
+	// filepaths in the Include directive
16
+	system bool
17
+	depth  uint8
18
+}
19
+
20
+type sshParserStateFn func() sshParserStateFn
21
+
22
+// Formats and panics an error message based on a token
23
+func (p *sshParser) raiseErrorf(tok *token, msg string, args ...interface{}) {
24
+	// TODO this format is ugly
25
+	panic(tok.Position.String() + ": " + fmt.Sprintf(msg, args...))
26
+}
27
+
28
+func (p *sshParser) raiseError(tok *token, err error) {
29
+	if err == ErrDepthExceeded {
30
+		panic(err)
31
+	}
32
+	// TODO this format is ugly
33
+	panic(tok.Position.String() + ": " + err.Error())
34
+}
35
+
36
+func (p *sshParser) run() {
37
+	for state := p.parseStart; state != nil; {
38
+		state = state()
39
+	}
40
+}
41
+
42
+func (p *sshParser) peek() *token {
43
+	if len(p.tokensBuffer) != 0 {
44
+		return &(p.tokensBuffer[0])
45
+	}
46
+
47
+	tok, ok := <-p.flow
48
+	if !ok {
49
+		return nil
50
+	}
51
+	p.tokensBuffer = append(p.tokensBuffer, tok)
52
+	return &tok
53
+}
54
+
55
+func (p *sshParser) getToken() *token {
56
+	if len(p.tokensBuffer) != 0 {
57
+		tok := p.tokensBuffer[0]
58
+		p.tokensBuffer = p.tokensBuffer[1:]
59
+		return &tok
60
+	}
61
+	tok, ok := <-p.flow
62
+	if !ok {
63
+		return nil
64
+	}
65
+	return &tok
66
+}
67
+
68
+func (p *sshParser) parseStart() sshParserStateFn {
69
+	tok := p.peek()
70
+
71
+	// end of stream, parsing is finished
72
+	if tok == nil {
73
+		return nil
74
+	}
75
+
76
+	switch tok.typ {
77
+	case tokenComment, tokenEmptyLine:
78
+		return p.parseComment
79
+	case tokenKey:
80
+		return p.parseKV
81
+	case tokenEOF:
82
+		return nil
83
+	default:
84
+		p.raiseErrorf(tok, fmt.Sprintf("unexpected token %q\n", tok))
85
+	}
86
+	return nil
87
+}
88
+
89
+func (p *sshParser) parseKV() sshParserStateFn {
90
+	key := p.getToken()
91
+	hasEquals := false
92
+	val := p.getToken()
93
+	if val.typ == tokenEquals {
94
+		hasEquals = true
95
+		val = p.getToken()
96
+	}
97
+	comment := ""
98
+	tok := p.peek()
99
+	if tok.typ == tokenComment && tok.Position.Line == val.Position.Line {
100
+		tok = p.getToken()
101
+		comment = tok.val
102
+	}
103
+	if strings.ToLower(key.val) == "match" {
104
+		// https://github.com/kevinburke/ssh_config/issues/6
105
+		p.raiseErrorf(val, "ssh_config: Match directive parsing is unsupported")
106
+		return nil
107
+	}
108
+	if strings.ToLower(key.val) == "host" {
109
+		strPatterns := strings.Split(val.val, " ")
110
+		patterns := make([]*Pattern, 0)
111
+		for i := range strPatterns {
112
+			if strPatterns[i] == "" {
113
+				continue
114
+			}
115
+			pat, err := NewPattern(strPatterns[i])
116
+			if err != nil {
117
+				p.raiseErrorf(val, "Invalid host pattern: %v", err)
118
+				return nil
119
+			}
120
+			patterns = append(patterns, pat)
121
+		}
122
+		p.config.Hosts = append(p.config.Hosts, &Host{
123
+			Patterns:   patterns,
124
+			Nodes:      make([]Node, 0),
125
+			EOLComment: comment,
126
+			hasEquals:  hasEquals,
127
+		})
128
+		return p.parseStart
129
+	}
130
+	lastHost := p.config.Hosts[len(p.config.Hosts)-1]
131
+	if strings.ToLower(key.val) == "include" {
132
+		inc, err := NewInclude(strings.Split(val.val, " "), hasEquals, key.Position, comment, p.system, p.depth+1)
133
+		if err == ErrDepthExceeded {
134
+			p.raiseError(val, err)
135
+			return nil
136
+		}
137
+		if err != nil {
138
+			p.raiseErrorf(val, "Error parsing Include directive: %v", err)
139
+			return nil
140
+		}
141
+		lastHost.Nodes = append(lastHost.Nodes, inc)
142
+		return p.parseStart
143
+	}
144
+	kv := &KV{
145
+		Key:          key.val,
146
+		Value:        val.val,
147
+		Comment:      comment,
148
+		hasEquals:    hasEquals,
149
+		leadingSpace: uint16(key.Position.Col) - 1,
150
+		position:     key.Position,
151
+	}
152
+	lastHost.Nodes = append(lastHost.Nodes, kv)
153
+	return p.parseStart
154
+}
155
+
156
+func (p *sshParser) parseComment() sshParserStateFn {
157
+	comment := p.getToken()
158
+	lastHost := p.config.Hosts[len(p.config.Hosts)-1]
159
+	lastHost.Nodes = append(lastHost.Nodes, &Empty{
160
+		Comment: comment.val,
161
+		// account for the "#" as well
162
+		leadingSpace: comment.Position.Col - 2,
163
+		position:     comment.Position,
164
+	})
165
+	return p.parseStart
166
+}
167
+
168
+func parseSSH(flow chan token, system bool, depth uint8) *Config {
169
+	result := newConfig()
170
+	result.position = Position{1, 1}
171
+	parser := &sshParser{
172
+		flow:          flow,
173
+		config:        result,
174
+		tokensBuffer:  make([]token, 0),
175
+		currentTable:  make([]string, 0),
176
+		seenTableKeys: make([]string, 0),
177
+		system:        system,
178
+		depth:         depth,
179
+	}
180
+	parser.run()
181
+	return result
182
+}

+ 25
- 0
vendor/src/github.com/kevinburke/ssh_config/position.go 查看文件

@@ -0,0 +1,25 @@
1
+package ssh_config
2
+
3
+import "fmt"
4
+
5
+// Position of a document element within a SSH document.
6
+//
7
+// Line and Col are both 1-indexed positions for the element's line number and
8
+// column number, respectively.  Values of zero or less will cause Invalid(),
9
+// to return true.
10
+type Position struct {
11
+	Line uint32 // line within the document
12
+	Col  uint16 // column within the line
13
+}
14
+
15
+// String representation of the position.
16
+// Displays 1-indexed line and column numbers.
17
+func (p Position) String() string {
18
+	return fmt.Sprintf("(%d, %d)", p.Line, p.Col)
19
+}
20
+
21
+// Invalid returns whether or not the position is valid (i.e. with negative or
22
+// null values)
23
+func (p Position) Invalid() bool {
24
+	return p.Line <= 0 || p.Col <= 0
25
+}

+ 3
- 0
vendor/src/github.com/kevinburke/ssh_config/testdata/anotherfile 查看文件

@@ -0,0 +1,3 @@
1
+# Not sure that this actually works; Include might need to be relative to the
2
+# load directory.
3
+Compression yes

+ 39
- 0
vendor/src/github.com/kevinburke/ssh_config/testdata/config1 查看文件

@@ -0,0 +1,39 @@
1
+Host localhost 127.0.0.1 # A comment at the end of a host line.
2
+  NoHostAuthenticationForLocalhost yes
3
+
4
+# A comment
5
+    # A comment with leading spaces.
6
+
7
+Host wap
8
+  User root
9
+  KexAlgorithms diffie-hellman-group1-sha1
10
+
11
+Host [some stuff behind a NAT]
12
+  Compression yes
13
+  ProxyCommand ssh -qW %h:%p [NATrouter]
14
+
15
+Host wopr # there are 2 proxies available for this one...
16
+  User root
17
+  ProxyCommand sh -c "ssh proxy1 -qW %h:22 || ssh proxy2 -qW %h:22"
18
+
19
+Host dhcp-??
20
+  UserKnownHostsFile /dev/null
21
+  StrictHostKeyChecking no
22
+  User root
23
+
24
+Host [my boxes] [*.mydomain]
25
+  ForwardAgent yes
26
+  ForwardX11 yes
27
+  ForwardX11Trusted yes
28
+
29
+Host *
30
+  #ControlMaster auto
31
+  #ControlPath /tmp/ssh-master-%C
32
+  #ControlPath /tmp/ssh-%u-%r@%h:%p
33
+  #ControlPersist yes
34
+  ForwardX11Timeout 52w
35
+  XAuthLocation /usr/bin/xauth
36
+  SendEnv LANG LC_*
37
+  HostKeyAlgorithms ssh-ed25519,ssh-rsa
38
+  AddressFamily inet
39
+  #UpdateHostKeys ask

+ 50
- 0
vendor/src/github.com/kevinburke/ssh_config/testdata/config2 查看文件

@@ -0,0 +1,50 @@
1
+#	$OpenBSD: ssh_config,v 1.30 2016/02/20 23:06:23 sobrado Exp $
2
+
3
+# This is the ssh client system-wide configuration file.  See
4
+# ssh_config(5) for more information.  This file provides defaults for
5
+# users, and the values can be changed in per-user configuration files
6
+# or on the command line.
7
+
8
+# Configuration data is parsed as follows:
9
+#  1. command line options
10
+#  2. user-specific file
11
+#  3. system-wide file
12
+# Any configuration value is only changed the first time it is set.
13
+# Thus, host-specific definitions should be at the beginning of the
14
+# configuration file, and defaults at the end.
15
+
16
+# Site-wide defaults for some commonly used options.  For a comprehensive
17
+# list of available options, their meanings and defaults, please see the
18
+# ssh_config(5) man page.
19
+
20
+# Host *
21
+#   ForwardAgent no
22
+#   ForwardX11 no
23
+#   RhostsRSAAuthentication no
24
+#   RSAAuthentication yes
25
+#   PasswordAuthentication yes
26
+#   HostbasedAuthentication no
27
+#   GSSAPIAuthentication no
28
+#   GSSAPIDelegateCredentials no
29
+#   BatchMode no
30
+#   CheckHostIP yes
31
+#   AddressFamily any
32
+#   ConnectTimeout 0
33
+#   StrictHostKeyChecking ask
34
+#   IdentityFile ~/.ssh/identity
35
+#   IdentityFile ~/.ssh/id_rsa
36
+#   IdentityFile ~/.ssh/id_dsa
37
+#   IdentityFile ~/.ssh/id_ecdsa
38
+#   IdentityFile ~/.ssh/id_ed25519
39
+#   Port 22
40
+#   Protocol 2
41
+#   Cipher 3des
42
+#   Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc
43
+#   MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160
44
+#   EscapeChar ~
45
+#   Tunnel no
46
+#   TunnelDevice any:any
47
+#   PermitLocalCommand no
48
+#   VisualHostKey no
49
+#   ProxyCommand ssh -q -W %h:%p gateway.example.com
50
+#   RekeyLimit 1G 1h

+ 31
- 0
vendor/src/github.com/kevinburke/ssh_config/testdata/config3 查看文件

@@ -0,0 +1,31 @@
1
+Host bastion.*.i.*.example.net
2
+  User simon.thulbourn
3
+  Port 22
4
+  ForwardAgent yes
5
+  IdentityFile /Users/%u/.ssh/example.net/%r/id_rsa
6
+  UseKeychain yes
7
+
8
+Host 10.*
9
+  User simon.thulbourn
10
+  Port 23
11
+  ForwardAgent yes
12
+  StrictHostKeyChecking no
13
+  UserKnownHostsFile /dev/null
14
+  IdentityFile /Users/%u/.ssh/example.net/%r/id_rsa
15
+  UseKeychain yes
16
+  ProxyCommand >&1; h="%h"; exec ssh -q $(ssh-bastion -ip $h) nc %h %p
17
+
18
+Host 20.20.20.?
19
+  User simon.thulbourn
20
+  Port 24
21
+  ForwardAgent yes
22
+  StrictHostKeyChecking no
23
+  UserKnownHostsFile /dev/null
24
+  IdentityFile /Users/%u/.ssh/example.net/%r/id_rsa
25
+  UseKeychain yes
26
+  ProxyCommand >&1; h="%h"; exec ssh -q $(ssh-bastion -ip $h) nc %h %p
27
+
28
+Host *
29
+  IdentityFile /Users/%u/.ssh/%h/%r/id_rsa
30
+  UseKeychain yes
31
+  Port 25

+ 4
- 0
vendor/src/github.com/kevinburke/ssh_config/testdata/config4 查看文件

@@ -0,0 +1,4 @@
1
+# Extra space at end of line is important.
2
+Host wap     
3
+  User root
4
+  KexAlgorithms diffie-hellman-group1-sha1

+ 4
- 0
vendor/src/github.com/kevinburke/ssh_config/testdata/eqsign 查看文件

@@ -0,0 +1,4 @@
1
+Host=test.test
2
+  Port =1234
3
+  Port2= 5678
4
+  Compression yes

+ 2
- 0
vendor/src/github.com/kevinburke/ssh_config/testdata/extraspace 查看文件

@@ -0,0 +1,2 @@
1
+Host test.test
2
+  Port      1234

+ 4
- 0
vendor/src/github.com/kevinburke/ssh_config/testdata/include 查看文件

@@ -0,0 +1,4 @@
1
+Host kevinburke.ssh_config.test.example.com
2
+    # This file (or files) needs to be found in ~/.ssh or /etc/ssh, depending on
3
+    # the test.
4
+    Include kevinburke-ssh-config-*-file

+ 4
- 0
vendor/src/github.com/kevinburke/ssh_config/testdata/include-recursive 查看文件

@@ -0,0 +1,4 @@
1
+Host kevinburke.ssh_config.test.example.com
2
+	# This file (or files) needs to be found in ~/.ssh or /etc/ssh, depending on
3
+	# the test. It should include itself.
4
+	Include kevinburke-ssh-config-recursive-include

+ 2
- 0
vendor/src/github.com/kevinburke/ssh_config/testdata/invalid-port 查看文件

@@ -0,0 +1,2 @@
1
+Host test.test
2
+  Port notanumber

+ 2
- 0
vendor/src/github.com/kevinburke/ssh_config/testdata/match-directive 查看文件

@@ -0,0 +1,2 @@
1
+Match all
2
+	Port 4567

+ 5
- 0
vendor/src/github.com/kevinburke/ssh_config/testdata/negated 查看文件

@@ -0,0 +1,5 @@
1
+Host *.example.com !*.dialup.example.com
2
+  Port 1234
3
+
4
+Host *
5
+  Port 5678

+ 0
- 0
vendor/src/github.com/kevinburke/ssh_config/testdata/system-include 查看文件


+ 49
- 0
vendor/src/github.com/kevinburke/ssh_config/token.go 查看文件

@@ -0,0 +1,49 @@
1
+package ssh_config
2
+
3
+import "fmt"
4
+
5
+type token struct {
6
+	Position
7
+	typ tokenType
8
+	val string
9
+}
10
+
11
+func (t token) String() string {
12
+	switch t.typ {
13
+	case tokenEOF:
14
+		return "EOF"
15
+	}
16
+	return fmt.Sprintf("%q", t.val)
17
+}
18
+
19
+type tokenType int
20
+
21
+const (
22
+	eof = -(iota + 1)
23
+)
24
+
25
+const (
26
+	tokenError tokenType = iota
27
+	tokenEOF
28
+	tokenEmptyLine
29
+	tokenComment
30
+	tokenKey
31
+	tokenEquals
32
+	tokenString
33
+)
34
+
35
+func isSpace(r rune) bool {
36
+	return r == ' ' || r == '\t'
37
+}
38
+
39
+func isKeyStartChar(r rune) bool {
40
+	return !(isSpace(r) || r == '\r' || r == '\n' || r == eof)
41
+}
42
+
43
+// I'm not sure that this is correct
44
+func isKeyChar(r rune) bool {
45
+	// Keys start with the first character that isn't whitespace or [ and end
46
+	// with the last non-whitespace character before the equals sign. Keys
47
+	// cannot contain a # character."
48
+	return !(r == '\r' || r == '\n' || r == eof || r == '=')
49
+}

+ 162
- 0
vendor/src/github.com/kevinburke/ssh_config/validators.go 查看文件

@@ -0,0 +1,162 @@
1
+package ssh_config
2
+
3
+import (
4
+	"fmt"
5
+	"strconv"
6
+	"strings"
7
+)
8
+
9
+// Default returns the default value for the given keyword, for example "22" if
10
+// the keyword is "Port". Default returns the empty string if the keyword has no
11
+// default, or if the keyword is unknown. Keyword matching is case-insensitive.
12
+//
13
+// Default values are provided by OpenSSH_7.4p1 on a Mac.
14
+func Default(keyword string) string {
15
+	return defaults[strings.ToLower(keyword)]
16
+}
17
+
18
+// Arguments where the value must be "yes" or "no" and *only* yes or no.
19
+var yesnos = map[string]bool{
20
+	strings.ToLower("BatchMode"):                        true,
21
+	strings.ToLower("CanonicalizeFallbackLocal"):        true,
22
+	strings.ToLower("ChallengeResponseAuthentication"):  true,
23
+	strings.ToLower("CheckHostIP"):                      true,
24
+	strings.ToLower("ClearAllForwardings"):              true,
25
+	strings.ToLower("Compression"):                      true,
26
+	strings.ToLower("EnableSSHKeysign"):                 true,
27
+	strings.ToLower("ExitOnForwardFailure"):             true,
28
+	strings.ToLower("ForwardAgent"):                     true,
29
+	strings.ToLower("ForwardX11"):                       true,
30
+	strings.ToLower("ForwardX11Trusted"):                true,
31
+	strings.ToLower("GatewayPorts"):                     true,
32
+	strings.ToLower("GSSAPIAuthentication"):             true,
33
+	strings.ToLower("GSSAPIDelegateCredentials"):        true,
34
+	strings.ToLower("HostbasedAuthentication"):          true,
35
+	strings.ToLower("IdentitiesOnly"):                   true,
36
+	strings.ToLower("KbdInteractiveAuthentication"):     true,
37
+	strings.ToLower("NoHostAuthenticationForLocalhost"): true,
38
+	strings.ToLower("PasswordAuthentication"):           true,
39
+	strings.ToLower("PermitLocalCommand"):               true,
40
+	strings.ToLower("PubkeyAuthentication"):             true,
41
+	strings.ToLower("RhostsRSAAuthentication"):          true,
42
+	strings.ToLower("RSAAuthentication"):                true,
43
+	strings.ToLower("StreamLocalBindUnlink"):            true,
44
+	strings.ToLower("TCPKeepAlive"):                     true,
45
+	strings.ToLower("UseKeychain"):                      true,
46
+	strings.ToLower("UsePrivilegedPort"):                true,
47
+	strings.ToLower("VisualHostKey"):                    true,
48
+}
49
+
50
+var uints = map[string]bool{
51
+	strings.ToLower("CanonicalizeMaxDots"):     true,
52
+	strings.ToLower("CompressionLevel"):        true, // 1 to 9
53
+	strings.ToLower("ConnectionAttempts"):      true,
54
+	strings.ToLower("ConnectTimeout"):          true,
55
+	strings.ToLower("NumberOfPasswordPrompts"): true,
56
+	strings.ToLower("Port"):                    true,
57
+	strings.ToLower("ServerAliveCountMax"):     true,
58
+	strings.ToLower("ServerAliveInterval"):     true,
59
+}
60
+
61
+func mustBeYesOrNo(lkey string) bool {
62
+	return yesnos[lkey]
63
+}
64
+
65
+func mustBeUint(lkey string) bool {
66
+	return uints[lkey]
67
+}
68
+
69
+func validate(key, val string) error {
70
+	lkey := strings.ToLower(key)
71
+	if mustBeYesOrNo(lkey) && (val != "yes" && val != "no") {
72
+		return fmt.Errorf("ssh_config: value for key %q must be 'yes' or 'no', got %q", key, val)
73
+	}
74
+	if mustBeUint(lkey) {
75
+		_, err := strconv.ParseUint(val, 10, 64)
76
+		if err != nil {
77
+			return fmt.Errorf("ssh_config: %v", err)
78
+		}
79
+	}
80
+	return nil
81
+}
82
+
83
+var defaults = map[string]string{
84
+	strings.ToLower("AddKeysToAgent"):                  "no",
85
+	strings.ToLower("AddressFamily"):                   "any",
86
+	strings.ToLower("BatchMode"):                       "no",
87
+	strings.ToLower("CanonicalizeFallbackLocal"):       "yes",
88
+	strings.ToLower("CanonicalizeHostname"):            "no",
89
+	strings.ToLower("CanonicalizeMaxDots"):             "1",
90
+	strings.ToLower("ChallengeResponseAuthentication"): "yes",
91
+	strings.ToLower("CheckHostIP"):                     "yes",
92
+	// TODO is this still the correct cipher
93
+	strings.ToLower("Cipher"):                    "3des",
94
+	strings.ToLower("Ciphers"):                   "chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc",
95
+	strings.ToLower("ClearAllForwardings"):       "no",
96
+	strings.ToLower("Compression"):               "no",
97
+	strings.ToLower("CompressionLevel"):          "6",
98
+	strings.ToLower("ConnectionAttempts"):        "1",
99
+	strings.ToLower("ControlMaster"):             "no",
100
+	strings.ToLower("EnableSSHKeysign"):          "no",
101
+	strings.ToLower("EscapeChar"):                "~",
102
+	strings.ToLower("ExitOnForwardFailure"):      "no",
103
+	strings.ToLower("FingerprintHash"):           "sha256",
104
+	strings.ToLower("ForwardAgent"):              "no",
105
+	strings.ToLower("ForwardX11"):                "no",
106
+	strings.ToLower("ForwardX11Timeout"):         "20m",
107
+	strings.ToLower("ForwardX11Trusted"):         "no",
108
+	strings.ToLower("GatewayPorts"):              "no",
109
+	strings.ToLower("GlobalKnownHostsFile"):      "/etc/ssh/ssh_known_hosts /etc/ssh/ssh_known_hosts2",
110
+	strings.ToLower("GSSAPIAuthentication"):      "no",
111
+	strings.ToLower("GSSAPIDelegateCredentials"): "no",
112
+	strings.ToLower("HashKnownHosts"):            "no",
113
+	strings.ToLower("HostbasedAuthentication"):   "no",
114
+
115
+	strings.ToLower("HostbasedKeyTypes"): "ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,ssh-ed25519-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519,ssh-rsa",
116
+	strings.ToLower("HostKeyAlgorithms"): "ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,ssh-ed25519-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519,ssh-rsa",
117
+	// HostName has a dynamic default (the value passed at the command line).
118
+
119
+	strings.ToLower("IdentitiesOnly"): "no",
120
+	strings.ToLower("IdentityFile"):   "~/.ssh/identity",
121
+
122
+	// IPQoS has a dynamic default based on interactive or non-interactive
123
+	// sessions.
124
+
125
+	strings.ToLower("KbdInteractiveAuthentication"): "yes",
126
+
127
+	strings.ToLower("KexAlgorithms"): "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1",
128
+	strings.ToLower("LogLevel"):      "INFO",
129
+	strings.ToLower("MACs"):          "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1",
130
+
131
+	strings.ToLower("NoHostAuthenticationForLocalhost"): "no",
132
+	strings.ToLower("NumberOfPasswordPrompts"):          "3",
133
+	strings.ToLower("PasswordAuthentication"):           "yes",
134
+	strings.ToLower("PermitLocalCommand"):               "no",
135
+	strings.ToLower("Port"):                             "22",
136
+
137
+	strings.ToLower("PreferredAuthentications"): "gssapi-with-mic,hostbased,publickey,keyboard-interactive,password",
138
+	strings.ToLower("Protocol"):                 "2",
139
+	strings.ToLower("ProxyUseFdpass"):           "no",
140
+	strings.ToLower("PubkeyAcceptedKeyTypes"):   "ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,ssh-ed25519-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519,ssh-rsa",
141
+	strings.ToLower("PubkeyAuthentication"):     "yes",
142
+	strings.ToLower("RekeyLimit"):               "default none",
143
+	strings.ToLower("RhostsRSAAuthentication"):  "no",
144
+	strings.ToLower("RSAAuthentication"):        "yes",
145
+
146
+	strings.ToLower("ServerAliveCountMax"):   "3",
147
+	strings.ToLower("ServerAliveInterval"):   "0",
148
+	strings.ToLower("StreamLocalBindMask"):   "0177",
149
+	strings.ToLower("StreamLocalBindUnlink"): "no",
150
+	strings.ToLower("StrictHostKeyChecking"): "ask",
151
+	strings.ToLower("TCPKeepAlive"):          "yes",
152
+	strings.ToLower("Tunnel"):                "no",
153
+	strings.ToLower("TunnelDevice"):          "any:any",
154
+	strings.ToLower("UpdateHostKeys"):        "no",
155
+	strings.ToLower("UseKeychain"):           "no",
156
+	strings.ToLower("UsePrivilegedPort"):     "no",
157
+
158
+	strings.ToLower("UserKnownHostsFile"): "~/.ssh/known_hosts ~/.ssh/known_hosts2",
159
+	strings.ToLower("VerifyHostKeyDNS"):   "no",
160
+	strings.ToLower("VisualHostKey"):      "no",
161
+	strings.ToLower("XAuthLocation"):      "/usr/X11R6/bin/xauth",
162
+}

+ 44
- 0
vendor/src/github.com/kevinburke/ssh_config/validators_test.go 查看文件

@@ -0,0 +1,44 @@
1
+package ssh_config
2
+
3
+import (
4
+	"testing"
5
+)
6
+
7
+var validateTests = []struct {
8
+	key string
9
+	val string
10
+	err string
11
+}{
12
+	{"IdentitiesOnly", "yes", ""},
13
+	{"IdentitiesOnly", "Yes", `ssh_config: value for key "IdentitiesOnly" must be 'yes' or 'no', got "Yes"`},
14
+	{"Port", "22", ``},
15
+	{"Port", "yes", `ssh_config: strconv.ParseUint: parsing "yes": invalid syntax`},
16
+}
17
+
18
+func TestValidate(t *testing.T) {
19
+	for _, tt := range validateTests {
20
+		err := validate(tt.key, tt.val)
21
+		if tt.err == "" && err != nil {
22
+			t.Errorf("validate(%q, %q): got %v, want nil", tt.key, tt.val, err)
23
+		}
24
+		if tt.err != "" {
25
+			if err == nil {
26
+				t.Errorf("validate(%q, %q): got nil error, want %v", tt.key, tt.val, tt.err)
27
+			} else if err.Error() != tt.err {
28
+				t.Errorf("validate(%q, %q): got err %v, want %v", tt.key, tt.val, err, tt.err)
29
+			}
30
+		}
31
+	}
32
+}
33
+
34
+func TestDefault(t *testing.T) {
35
+	if v := Default("VisualHostKey"); v != "no" {
36
+		t.Errorf("Default(%q): got %v, want 'no'", "VisualHostKey", v)
37
+	}
38
+	if v := Default("visualhostkey"); v != "no" {
39
+		t.Errorf("Default(%q): got %v, want 'no'", "visualhostkey", v)
40
+	}
41
+	if v := Default("notfound"); v != "" {
42
+		t.Errorf("Default(%q): got %v, want ''", "notfound", v)
43
+	}
44
+}

+ 61
- 0
vendor/src/github.com/pelletier/go-buffruneio/README.md 查看文件

@@ -0,0 +1,61 @@
1
+# buffruneio
2
+
3
+[![Tests Status](https://travis-ci.org/pelletier/go-buffruneio.svg?branch=master)](https://travis-ci.org/pelletier/go-buffruneio)
4
+[![GoDoc](https://godoc.org/github.com/pelletier/go-buffruneio?status.svg)](https://godoc.org/github.com/pelletier/go-buffruneio)
5
+
6
+Buffruneio provides rune-based buffered input.
7
+
8
+```go
9
+import "github.com/pelletier/go-buffruneio"
10
+```
11
+
12
+## Examples
13
+
14
+```go
15
+import (
16
+    "fmt"
17
+    "github.com/pelletier/go-buffruneio"
18
+    "strings"
19
+)
20
+
21
+reader := buffruneio.NewReader(strings.NewReader("abcd"))
22
+fmt.Println(reader.ReadRune()) // 'a'
23
+fmt.Println(reader.ReadRune()) // 'b'
24
+fmt.Println(reader.ReadRune()) // 'c'
25
+reader.UnreadRune()
26
+reader.UnreadRune()
27
+fmt.Println(reader.ReadRune()) // 'b'
28
+fmt.Println(reader.ReadRune()) // 'c'
29
+```
30
+
31
+## Documentation
32
+
33
+The documentation and additional examples are available at
34
+[godoc.org](http://godoc.org/github.com/pelletier/go-buffruneio).
35
+
36
+## Contribute
37
+
38
+Feel free to report bugs and patches using GitHub's pull requests system on
39
+[pelletier/go-buffruneio](https://github.com/pelletier/go-buffruneio). Any feedback is
40
+much appreciated!
41
+
42
+## LICENSE
43
+
44
+Copyright (c) 2016 - 2018 Thomas Pelletier
45
+
46
+Permission is hereby granted, free of charge, to any person obtaining a copy of
47
+this software and associated documentation files (the "Software"), to deal in
48
+the Software without restriction, including without limitation the rights to
49
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
50
+the Software, and to permit persons to whom the Software is furnished to do so,
51
+subject to the following conditions:
52
+
53
+The above copyright notice and this permission notice shall be included in all
54
+copies or substantial portions of the Software.
55
+
56
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
57
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
58
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
59
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
60
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
61
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ 133
- 0
vendor/src/github.com/pelletier/go-buffruneio/buffruneio.go 查看文件

@@ -0,0 +1,133 @@
1
+// Package buffruneio provides rune-based buffered input.
2
+package buffruneio
3
+
4
+import (
5
+	"bufio"
6
+	"errors"
7
+	"io"
8
+	"unicode/utf8"
9
+)
10
+
11
+// EOF is a rune value indicating end-of-file.
12
+const EOF = -1
13
+
14
+// ErrNoRuneToUnread is the error returned when UnreadRune is called with nothing to unread.
15
+var ErrNoRuneToUnread = errors.New("no rune to unwind")
16
+
17
+// A Reader implements rune-based input for an underlying byte stream.
18
+type Reader struct {
19
+	buffer  []rune
20
+	current int
21
+	input   *bufio.Reader
22
+}
23
+
24
+// NewReader returns a new Reader reading the given input.
25
+func NewReader(input io.Reader) *Reader {
26
+	return &Reader{
27
+		input: bufio.NewReader(input),
28
+	}
29
+}
30
+
31
+// The rune buffer stores -2 to represent RuneError of length 1 (UTF-8 decoding errors).
32
+const badRune = -2
33
+
34
+// feedBuffer adds a rune to the buffer.
35
+// If EOF is reached, it adds EOF to the buffer and returns nil.
36
+// If a different error is encountered, it returns the error without
37
+// adding to the buffer.
38
+func (rd *Reader) feedBuffer() error {
39
+	if rd.buffer == nil {
40
+		rd.buffer = make([]rune, 0, 256)
41
+	}
42
+	r, size, err := rd.input.ReadRune()
43
+	if err != nil {
44
+		if err != io.EOF {
45
+			return err
46
+		}
47
+		r = EOF
48
+	}
49
+	if r == utf8.RuneError && size == 1 {
50
+		r = badRune
51
+	}
52
+	rd.buffer = append(rd.buffer, r)
53
+	return nil
54
+}
55
+
56
+// ReadRune reads and returns the next rune from the input.
57
+// The rune is also saved in an internal buffer, in case UnreadRune is called.
58
+// To avoid unbounded buffer growth, the caller must call Forget at appropriate intervals.
59
+//
60
+// At end of file, ReadRune returns EOF, 0, nil.
61
+// On read errors other than io.EOF, ReadRune returns EOF, 0, err.
62
+func (rd *Reader) ReadRune() (rune, int, error) {
63
+	if rd.current >= len(rd.buffer) {
64
+		if err := rd.feedBuffer(); err != nil {
65
+			return EOF, 0, err
66
+		}
67
+	}
68
+	r := rd.buffer[rd.current]
69
+	rd.current++
70
+	if r == badRune {
71
+		return utf8.RuneError, 1, nil
72
+	}
73
+	if r == EOF {
74
+		return EOF, 0, nil
75
+	}
76
+	return r, utf8.RuneLen(r), nil
77
+}
78
+
79
+// UnreadRune rewinds the input by one rune, undoing the effect of a single ReadRune call.
80
+// UnreadRune may be called multiple times to rewind a sequence of ReadRune calls,
81
+// up to the last time Forget was called or the beginning of the input.
82
+//
83
+// If there are no ReadRune calls left to undo, UnreadRune returns ErrNoRuneToUnread.
84
+func (rd *Reader) UnreadRune() error {
85
+	if rd.current == 0 {
86
+		return ErrNoRuneToUnread
87
+	}
88
+	rd.current--
89
+	return nil
90
+}
91
+
92
+// Forget discards buffered runes before the current input position.
93
+// Calling Forget makes it impossible to UnreadRune earlier than the current input position
94
+// but is necessary to avoid unbounded buffer growth.
95
+func (rd *Reader) Forget() {
96
+	n := copy(rd.buffer, rd.buffer[rd.current:])
97
+	rd.current = 0
98
+	rd.buffer = rd.buffer[:n]
99
+}
100
+
101
+// PeekRunes returns the next n runes in the input,
102
+// without advancing the current input position.
103
+//
104
+// If the input has fewer than n runes and then returns
105
+// an io.EOF error, PeekRune returns a slice containing
106
+// the available runes followed by EOF.
107
+// On other hand, if the input ends early with a non-io.EOF error,
108
+// PeekRune returns a slice containing only the available runes,
109
+// with no terminating EOF.
110
+func (rd *Reader) PeekRunes(n int) []rune {
111
+	for len(rd.buffer)-rd.current < n && !rd.haveEOF() {
112
+		if err := rd.feedBuffer(); err != nil {
113
+			break
114
+		}
115
+	}
116
+
117
+	res := make([]rune, 0, n)
118
+	for i := 0; i < n; i++ {
119
+		r := rd.buffer[rd.current+i]
120
+		if r == badRune {
121
+			r = utf8.RuneError
122
+		}
123
+		res = append(res, r)
124
+		if r == EOF {
125
+			break
126
+		}
127
+	}
128
+	return res
129
+}
130
+
131
+func (rd *Reader) haveEOF() bool {
132
+	return rd.current < len(rd.buffer) && rd.buffer[len(rd.buffer)-1] == EOF
133
+}

+ 264
- 0
vendor/src/github.com/pelletier/go-buffruneio/buffruneio_test.go 查看文件

@@ -0,0 +1,264 @@
1
+package buffruneio
2
+
3
+import (
4
+	"reflect"
5
+	"runtime/debug"
6
+	"strings"
7
+	"testing"
8
+	"unicode/utf8"
9
+)
10
+
11
+func assertNoError(t *testing.T, err error) {
12
+	if err != nil {
13
+		t.Log("unexpected error", err)
14
+		debug.PrintStack()
15
+		t.FailNow()
16
+	}
17
+}
18
+
19
+func assumeRunesArray(t *testing.T, expected []rune, got []rune) {
20
+	if len(expected) != len(got) {
21
+		t.Fatal("expected", len(expected), "runes, but got", len(got))
22
+	}
23
+	for i := 0; i < len(got); i++ {
24
+		if expected[i] != got[i] {
25
+			t.Fatal("expected rune", expected[i], "at index", i, "but got", got[i])
26
+		}
27
+	}
28
+}
29
+
30
+func assumeRune(t *testing.T, rd *Reader, r rune) {
31
+	gotRune, size, err := rd.ReadRune()
32
+	wantSize := utf8.RuneLen(r)
33
+	if wantSize < 0 {
34
+		wantSize = 0
35
+	}
36
+	if gotRune != r || size != wantSize || err != nil {
37
+		t.Fatalf("ReadRune() = %q, %d, %v, wanted %q, %d, nil", gotRune, size, err, r, wantSize)
38
+	}
39
+}
40
+
41
+func assumeBadRune(t *testing.T, rd *Reader) {
42
+	gotRune, size, err := rd.ReadRune()
43
+	if gotRune != utf8.RuneError || size != 1 || err != nil {
44
+		t.Fatalf("ReadRune() = %q, %d, %v, wanted %q, 1, nil", gotRune, size, err, utf8.RuneError)
45
+	}
46
+}
47
+
48
+func TestReadString(t *testing.T) {
49
+	s := "hello"
50
+	rd := NewReader(strings.NewReader(s))
51
+
52
+	assumeRune(t, rd, 'h')
53
+	assumeRune(t, rd, 'e')
54
+	assumeRune(t, rd, 'l')
55
+	assumeRune(t, rd, 'l')
56
+	assumeRune(t, rd, 'o')
57
+	assumeRune(t, rd, EOF)
58
+}
59
+
60
+func TestMultipleEOF(t *testing.T) {
61
+	s := ""
62
+	rd := NewReader(strings.NewReader(s))
63
+
64
+	assumeRune(t, rd, EOF)
65
+	assumeRune(t, rd, EOF)
66
+}
67
+
68
+func TestBadRunes(t *testing.T) {
69
+	s := "ab\xff\ufffd\xffcd"
70
+	rd := NewReader(strings.NewReader(s))
71
+
72
+	assumeRune(t, rd, 'a')
73
+	assumeRune(t, rd, 'b')
74
+	assumeBadRune(t, rd)
75
+	assumeRune(t, rd, utf8.RuneError)
76
+	assumeBadRune(t, rd)
77
+	assumeRune(t, rd, 'c')
78
+	assumeRune(t, rd, 'd')
79
+
80
+	for i := 0; i < 6; i++ {
81
+		assertNoError(t, rd.UnreadRune())
82
+	}
83
+	assumeRune(t, rd, 'b')
84
+	assumeBadRune(t, rd)
85
+	assumeRune(t, rd, utf8.RuneError)
86
+	assumeBadRune(t, rd)
87
+	assumeRune(t, rd, 'c')
88
+	assumeRune(t, rd, 'd')
89
+}
90
+
91
+func TestUnread(t *testing.T) {
92
+	s := "ab"
93
+	rd := NewReader(strings.NewReader(s))
94
+
95
+	assumeRune(t, rd, 'a')
96
+	assumeRune(t, rd, 'b')
97
+	assertNoError(t, rd.UnreadRune())
98
+	assumeRune(t, rd, 'b')
99
+	assumeRune(t, rd, EOF)
100
+}
101
+
102
+func TestUnreadEOF(t *testing.T) {
103
+	s := "x"
104
+	rd := NewReader(strings.NewReader(s))
105
+
106
+	_ = rd.UnreadRune()
107
+	assumeRune(t, rd, 'x')
108
+	assumeRune(t, rd, EOF)
109
+	assumeRune(t, rd, EOF)
110
+	assertNoError(t, rd.UnreadRune())
111
+	assumeRune(t, rd, EOF)
112
+	assertNoError(t, rd.UnreadRune())
113
+	assertNoError(t, rd.UnreadRune())
114
+	assumeRune(t, rd, EOF)
115
+	assumeRune(t, rd, EOF)
116
+	assertNoError(t, rd.UnreadRune())
117
+	assertNoError(t, rd.UnreadRune())
118
+	assertNoError(t, rd.UnreadRune())
119
+	assumeRune(t, rd, 'x')
120
+	assumeRune(t, rd, EOF)
121
+	assumeRune(t, rd, EOF)
122
+}
123
+
124
+func TestForget(t *testing.T) {
125
+	s := "helio"
126
+	rd := NewReader(strings.NewReader(s))
127
+
128
+	assumeRune(t, rd, 'h')
129
+	assumeRune(t, rd, 'e')
130
+	assumeRune(t, rd, 'l')
131
+	assumeRune(t, rd, 'i')
132
+	rd.Forget()
133
+	if rd.UnreadRune() != ErrNoRuneToUnread {
134
+		t.Fatal("no rune should be available")
135
+	}
136
+	assumeRune(t, rd, 'o')
137
+}
138
+
139
+func TestForgetAfterUnread(t *testing.T) {
140
+	s := "helio"
141
+	rd := NewReader(strings.NewReader(s))
142
+
143
+	assumeRune(t, rd, 'h')
144
+	assumeRune(t, rd, 'e')
145
+	assumeRune(t, rd, 'l')
146
+	assumeRune(t, rd, 'i')
147
+	assertNoError(t, rd.UnreadRune())
148
+	rd.Forget()
149
+	if rd.UnreadRune() != ErrNoRuneToUnread {
150
+		t.Fatal("no rune should be available")
151
+	}
152
+	assumeRune(t, rd, 'i')
153
+	assumeRune(t, rd, 'o')
154
+}
155
+
156
+func TestForgetEmpty(t *testing.T) {
157
+	s := ""
158
+	rd := NewReader(strings.NewReader(s))
159
+
160
+	rd.Forget()
161
+	assumeRune(t, rd, EOF)
162
+	rd.Forget()
163
+}
164
+
165
+func TestPeekEmpty(t *testing.T) {
166
+	s := ""
167
+	rd := NewReader(strings.NewReader(s))
168
+
169
+	runes := rd.PeekRunes(1)
170
+	if len(runes) != 1 {
171
+		t.Fatal("incorrect number of runes", len(runes))
172
+	}
173
+	if runes[0] != EOF {
174
+		t.Fatal("incorrect rune", runes[0])
175
+	}
176
+}
177
+
178
+func TestPeek(t *testing.T) {
179
+	s := "a"
180
+	rd := NewReader(strings.NewReader(s))
181
+
182
+	runes := rd.PeekRunes(1)
183
+	assumeRunesArray(t, []rune{'a'}, runes)
184
+
185
+	runes = rd.PeekRunes(1)
186
+	assumeRunesArray(t, []rune{'a'}, runes)
187
+
188
+	assumeRune(t, rd, 'a')
189
+	runes = rd.PeekRunes(1)
190
+	assumeRunesArray(t, []rune{EOF}, runes)
191
+
192
+	assumeRune(t, rd, EOF)
193
+}
194
+
195
+func TestPeekLarge(t *testing.T) {
196
+	s := "abcdefg☺\xff☹"
197
+	rd := NewReader(strings.NewReader(s))
198
+
199
+	runes := rd.PeekRunes(100)
200
+	want := []rune{'a', 'b', 'c', 'd', 'e', 'f', 'g', '☺', utf8.RuneError, '☹', EOF}
201
+	if !reflect.DeepEqual(runes, want) {
202
+		t.Fatalf("PeekRunes(100) = %q, want %q", runes, want)
203
+	}
204
+}
205
+
206
+var bigString = strings.Repeat("abcdefghi☺\xff☹", 1024) // 16 kB
207
+
208
+const bigStringRunes = 12 * 1024 // 12k runes
209
+
210
+func BenchmarkRead16K(b *testing.B) {
211
+	// Read 16K with no unread, no forget.
212
+	benchmarkRead(b, 1, false)
213
+}
214
+
215
+func BenchmarkReadForget16K(b *testing.B) {
216
+	// Read 16K, forgetting every 128 runes.
217
+	benchmarkRead(b, 1, true)
218
+}
219
+
220
+func BenchmarkReadRewind16K(b *testing.B) {
221
+	// Read 16K, unread all, read that 16K again.
222
+	benchmarkRead(b, 2, false)
223
+}
224
+
225
+func benchmarkRead(b *testing.B, count int, forget bool) {
226
+	if len(bigString) != 16*1024 {
227
+		b.Fatal("wrong length for bigString")
228
+	}
229
+	sr0 := strings.NewReader(bigString)
230
+	sr := new(strings.Reader)
231
+	b.SetBytes(int64(len(bigString)))
232
+	b.ReportAllocs()
233
+	for i := 0; i < b.N; i++ {
234
+		*sr = *sr0
235
+		rd := NewReader(sr)
236
+		for repeat := 0; repeat < count; repeat++ {
237
+			for j := 0; j < bigStringRunes; j++ {
238
+				r, _, err := rd.ReadRune()
239
+				if err != nil {
240
+					b.Fatal(err)
241
+				}
242
+				if r == EOF {
243
+					b.Fatal("unexpected EOF")
244
+				}
245
+				if forget && j%128 == 127 {
246
+					rd.Forget()
247
+				}
248
+			}
249
+			r, _, err := rd.ReadRune()
250
+			if err != nil {
251
+				b.Fatal(err)
252
+			}
253
+			if r != EOF {
254
+				b.Fatalf("missing EOF - %q", r)
255
+			}
256
+			if repeat == count-1 {
257
+				break
258
+			}
259
+			for rd.UnreadRune() == nil {
260
+				// keep unreading
261
+			}
262
+		}
263
+	}
264
+}

+ 526
- 0
vendor/src/golang.org/x/crypto/cast5/cast5.go 查看文件

@@ -0,0 +1,526 @@
1
+// Copyright 2010 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
+
5
+// Package cast5 implements CAST5, as defined in RFC 2144. CAST5 is a common
6
+// OpenPGP cipher.
7
+package cast5 // import "golang.org/x/crypto/cast5"
8
+
9
+import "errors"
10
+
11
+const BlockSize = 8
12
+const KeySize = 16
13
+
14
+type Cipher struct {
15
+	masking [16]uint32
16
+	rotate  [16]uint8
17
+}
18
+
19
+func NewCipher(key []byte) (c *Cipher, err error) {
20
+	if len(key) != KeySize {
21
+		return nil, errors.New("CAST5: keys must be 16 bytes")
22
+	}
23
+
24
+	c = new(Cipher)
25
+	c.keySchedule(key)
26
+	return
27
+}
28
+
29
+func (c *Cipher) BlockSize() int {
30
+	return BlockSize
31
+}
32
+
33
+func (c *Cipher) Encrypt(dst, src []byte) {
34
+	l := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3])
35
+	r := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7])
36
+
37
+	l, r = r, l^f1(r, c.masking[0], c.rotate[0])
38
+	l, r = r, l^f2(r, c.masking[1], c.rotate[1])
39
+	l, r = r, l^f3(r, c.masking[2], c.rotate[2])
40
+	l, r = r, l^f1(r, c.masking[3], c.rotate[3])
41
+
42
+	l, r = r, l^f2(r, c.masking[4], c.rotate[4])
43
+	l, r = r, l^f3(r, c.masking[5], c.rotate[5])
44
+	l, r = r, l^f1(r, c.masking[6], c.rotate[6])
45
+	l, r = r, l^f2(r, c.masking[7], c.rotate[7])
46
+
47
+	l, r = r, l^f3(r, c.masking[8], c.rotate[8])
48
+	l, r = r, l^f1(r, c.masking[9], c.rotate[9])
49
+	l, r = r, l^f2(r, c.masking[10], c.rotate[10])
50
+	l, r = r, l^f3(r, c.masking[11], c.rotate[11])
51
+
52
+	l, r = r, l^f1(r, c.masking[12], c.rotate[12])
53
+	l, r = r, l^f2(r, c.masking[13], c.rotate[13])
54
+	l, r = r, l^f3(r, c.masking[14], c.rotate[14])
55
+	l, r = r, l^f1(r, c.masking[15], c.rotate[15])
56
+
57
+	dst[0] = uint8(r >> 24)
58
+	dst[1] = uint8(r >> 16)
59
+	dst[2] = uint8(r >> 8)
60
+	dst[3] = uint8(r)
61
+	dst[4] = uint8(l >> 24)
62
+	dst[5] = uint8(l >> 16)
63
+	dst[6] = uint8(l >> 8)
64
+	dst[7] = uint8(l)
65
+}
66
+
67
+func (c *Cipher) Decrypt(dst, src []byte) {
68
+	l := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3])
69
+	r := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7])
70
+
71
+	l, r = r, l^f1(r, c.masking[15], c.rotate[15])
72
+	l, r = r, l^f3(r, c.masking[14], c.rotate[14])
73
+	l, r = r, l^f2(r, c.masking[13], c.rotate[13])
74
+	l, r = r, l^f1(r, c.masking[12], c.rotate[12])
75
+
76
+	l, r = r, l^f3(r, c.masking[11], c.rotate[11])
77
+	l, r = r, l^f2(r, c.masking[10], c.rotate[10])
78
+	l, r = r, l^f1(r, c.masking[9], c.rotate[9])
79
+	l, r = r, l^f3(r, c.masking[8], c.rotate[8])
80
+
81
+	l, r = r, l^f2(r, c.masking[7], c.rotate[7])
82
+	l, r = r, l^f1(r, c.masking[6], c.rotate[6])
83
+	l, r = r, l^f3(r, c.masking[5], c.rotate[5])
84
+	l, r = r, l^f2(r, c.masking[4], c.rotate[4])
85
+
86
+	l, r = r, l^f1(r, c.masking[3], c.rotate[3])
87
+	l, r = r, l^f3(r, c.masking[2], c.rotate[2])
88
+	l, r = r, l^f2(r, c.masking[1], c.rotate[1])
89
+	l, r = r, l^f1(r, c.masking[0], c.rotate[0])
90
+
91
+	dst[0] = uint8(r >> 24)
92
+	dst[1] = uint8(r >> 16)
93
+	dst[2] = uint8(r >> 8)
94
+	dst[3] = uint8(r)
95
+	dst[4] = uint8(l >> 24)
96
+	dst[5] = uint8(l >> 16)
97
+	dst[6] = uint8(l >> 8)
98
+	dst[7] = uint8(l)
99
+}
100
+
101
+type keyScheduleA [4][7]uint8
102
+type keyScheduleB [4][5]uint8
103
+
104
+// keyScheduleRound contains the magic values for a round of the key schedule.
105
+// The keyScheduleA deals with the lines like:
106
+//   z0z1z2z3 = x0x1x2x3 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE] ^ S7[x8]
107
+// Conceptually, both x and z are in the same array, x first. The first
108
+// element describes which word of this array gets written to and the
109
+// second, which word gets read. So, for the line above, it's "4, 0", because
110
+// it's writing to the first word of z, which, being after x, is word 4, and
111
+// reading from the first word of x: word 0.
112
+//
113
+// Next are the indexes into the S-boxes. Now the array is treated as bytes. So
114
+// "xD" is 0xd. The first byte of z is written as "16 + 0", just to be clear
115
+// that it's z that we're indexing.
116
+//
117
+// keyScheduleB deals with lines like:
118
+//   K1 = S5[z8] ^ S6[z9] ^ S7[z7] ^ S8[z6] ^ S5[z2]
119
+// "K1" is ignored because key words are always written in order. So the five
120
+// elements are the S-box indexes. They use the same form as in keyScheduleA,
121
+// above.
122
+
123
+type keyScheduleRound struct{}
124
+type keySchedule []keyScheduleRound
125
+
126
+var schedule = []struct {
127
+	a keyScheduleA
128
+	b keyScheduleB
129
+}{
130
+	{
131
+		keyScheduleA{
132
+			{4, 0, 0xd, 0xf, 0xc, 0xe, 0x8},
133
+			{5, 2, 16 + 0, 16 + 2, 16 + 1, 16 + 3, 0xa},
134
+			{6, 3, 16 + 7, 16 + 6, 16 + 5, 16 + 4, 9},
135
+			{7, 1, 16 + 0xa, 16 + 9, 16 + 0xb, 16 + 8, 0xb},
136
+		},
137
+		keyScheduleB{
138
+			{16 + 8, 16 + 9, 16 + 7, 16 + 6, 16 + 2},
139
+			{16 + 0xa, 16 + 0xb, 16 + 5, 16 + 4, 16 + 6},
140
+			{16 + 0xc, 16 + 0xd, 16 + 3, 16 + 2, 16 + 9},
141
+			{16 + 0xe, 16 + 0xf, 16 + 1, 16 + 0, 16 + 0xc},
142
+		},
143
+	},
144
+	{
145
+		keyScheduleA{
146
+			{0, 6, 16 + 5, 16 + 7, 16 + 4, 16 + 6, 16 + 0},
147
+			{1, 4, 0, 2, 1, 3, 16 + 2},
148
+			{2, 5, 7, 6, 5, 4, 16 + 1},
149
+			{3, 7, 0xa, 9, 0xb, 8, 16 + 3},
150
+		},
151
+		keyScheduleB{
152
+			{3, 2, 0xc, 0xd, 8},
153
+			{1, 0, 0xe, 0xf, 0xd},
154
+			{7, 6, 8, 9, 3},
155
+			{5, 4, 0xa, 0xb, 7},
156
+		},
157
+	},
158
+	{
159
+		keyScheduleA{
160
+			{4, 0, 0xd, 0xf, 0xc, 0xe, 8},
161
+			{5, 2, 16 + 0, 16 + 2, 16 + 1, 16 + 3, 0xa},
162
+			{6, 3, 16 + 7, 16 + 6, 16 + 5, 16 + 4, 9},
163
+			{7, 1, 16 + 0xa, 16 + 9, 16 + 0xb, 16 + 8, 0xb},
164
+		},
165
+		keyScheduleB{
166
+			{16 + 3, 16 + 2, 16 + 0xc, 16 + 0xd, 16 + 9},
167
+			{16 + 1, 16 + 0, 16 + 0xe, 16 + 0xf, 16 + 0xc},
168
+			{16 + 7, 16 + 6, 16 + 8, 16 + 9, 16 + 2},
169
+			{16 + 5, 16 + 4, 16 + 0xa, 16 + 0xb, 16 + 6},
170
+		},
171
+	},
172
+	{
173
+		keyScheduleA{
174
+			{0, 6, 16 + 5, 16 + 7, 16 + 4, 16 + 6, 16 + 0},
175
+			{1, 4, 0, 2, 1, 3, 16 + 2},
176
+			{2, 5, 7, 6, 5, 4, 16 + 1},
177
+			{3, 7, 0xa, 9, 0xb, 8, 16 + 3},
178
+		},
179
+		keyScheduleB{
180
+			{8, 9, 7, 6, 3},
181
+			{0xa, 0xb, 5, 4, 7},
182
+			{0xc, 0xd, 3, 2, 8},
183
+			{0xe, 0xf, 1, 0, 0xd},
184
+		},
185
+	},
186
+}
187
+
188
+func (c *Cipher) keySchedule(in []byte) {
189
+	var t [8]uint32
190
+	var k [32]uint32
191
+
192
+	for i := 0; i < 4; i++ {
193
+		j := i * 4
194
+		t[i] = uint32(in[j])<<24 | uint32(in[j+1])<<16 | uint32(in[j+2])<<8 | uint32(in[j+3])
195
+	}
196
+
197
+	x := []byte{6, 7, 4, 5}
198
+	ki := 0
199
+
200
+	for half := 0; half < 2; half++ {
201
+		for _, round := range schedule {
202
+			for j := 0; j < 4; j++ {
203
+				var a [7]uint8
204
+				copy(a[:], round.a[j][:])
205
+				w := t[a[1]]
206
+				w ^= sBox[4][(t[a[2]>>2]>>(24-8*(a[2]&3)))&0xff]
207
+				w ^= sBox[5][(t[a[3]>>2]>>(24-8*(a[3]&3)))&0xff]
208
+				w ^= sBox[6][(t[a[4]>>2]>>(24-8*(a[4]&3)))&0xff]
209
+				w ^= sBox[7][(t[a[5]>>2]>>(24-8*(a[5]&3)))&0xff]
210
+				w ^= sBox[x[j]][(t[a[6]>>2]>>(24-8*(a[6]&3)))&0xff]
211
+				t[a[0]] = w
212
+			}
213
+
214
+			for j := 0; j < 4; j++ {
215
+				var b [5]uint8
216
+				copy(b[:], round.b[j][:])
217
+				w := sBox[4][(t[b[0]>>2]>>(24-8*(b[0]&3)))&0xff]
218
+				w ^= sBox[5][(t[b[1]>>2]>>(24-8*(b[1]&3)))&0xff]
219
+				w ^= sBox[6][(t[b[2]>>2]>>(24-8*(b[2]&3)))&0xff]
220
+				w ^= sBox[7][(t[b[3]>>2]>>(24-8*(b[3]&3)))&0xff]
221
+				w ^= sBox[4+j][(t[b[4]>>2]>>(24-8*(b[4]&3)))&0xff]
222
+				k[ki] = w
223
+				ki++
224
+			}
225
+		}
226
+	}
227
+
228
+	for i := 0; i < 16; i++ {
229
+		c.masking[i] = k[i]
230
+		c.rotate[i] = uint8(k[16+i] & 0x1f)
231
+	}
232
+}
233
+
234
+// These are the three 'f' functions. See RFC 2144, section 2.2.
235
+func f1(d, m uint32, r uint8) uint32 {
236
+	t := m + d
237
+	I := (t << r) | (t >> (32 - r))
238
+	return ((sBox[0][I>>24] ^ sBox[1][(I>>16)&0xff]) - sBox[2][(I>>8)&0xff]) + sBox[3][I&0xff]
239
+}
240
+
241
+func f2(d, m uint32, r uint8) uint32 {
242
+	t := m ^ d
243
+	I := (t << r) | (t >> (32 - r))
244
+	return ((sBox[0][I>>24] - sBox[1][(I>>16)&0xff]) + sBox[2][(I>>8)&0xff]) ^ sBox[3][I&0xff]
245
+}
246
+
247
+func f3(d, m uint32, r uint8) uint32 {
248
+	t := m - d
249
+	I := (t << r) | (t >> (32 - r))
250
+	return ((sBox[0][I>>24] + sBox[1][(I>>16)&0xff]) ^ sBox[2][(I>>8)&0xff]) - sBox[3][I&0xff]
251
+}
252
+
253
+var sBox = [8][256]uint32{
254
+	{
255
+		0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949,
256
+		0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e,
257
+		0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
258
+		0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0,
259
+		0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7,
260
+		0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935,
261
+		0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d,
262
+		0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50,
263
+		0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe,
264
+		0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3,
265
+		0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167,
266
+		0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291,
267
+		0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779,
268
+		0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2,
269
+		0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511,
270
+		0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d,
271
+		0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5,
272
+		0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324,
273
+		0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c,
274
+		0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc,
275
+		0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d,
276
+		0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96,
277
+		0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a,
278
+		0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d,
279
+		0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd,
280
+		0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6,
281
+		0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9,
282
+		0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872,
283
+		0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c,
284
+		0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e,
285
+		0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9,
286
+		0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf,
287
+	},
288
+	{
289
+		0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651,
290
+		0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3,
291
+		0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb,
292
+		0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806,
293
+		0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b,
294
+		0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359,
295
+		0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b,
296
+		0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c,
297
+		0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34,
298
+		0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb,
299
+		0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd,
300
+		0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860,
301
+		0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b,
302
+		0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304,
303
+		0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b,
304
+		0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf,
305
+		0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c,
306
+		0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13,
307
+		0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f,
308
+		0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6,
309
+		0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6,
310
+		0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58,
311
+		0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906,
312
+		0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d,
313
+		0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6,
314
+		0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4,
315
+		0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6,
316
+		0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f,
317
+		0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249,
318
+		0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
319
+		0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9,
320
+		0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1,
321
+	},
322
+	{
323
+		0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90,
324
+		0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5,
325
+		0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e,
326
+		0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240,
327
+		0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5,
328
+		0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,
329
+		0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71,
330
+		0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04,
331
+		0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82,
332
+		0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15,
333
+		0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2,
334
+		0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176,
335
+		0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148,
336
+		0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc,
337
+		0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
338
+		0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e,
339
+		0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51,
340
+		0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f,
341
+		0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a,
342
+		0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b,
343
+		0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,
344
+		0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5,
345
+		0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45,
346
+		0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536,
347
+		0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc,
348
+		0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0,
349
+		0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69,
350
+		0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2,
351
+		0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49,
352
+		0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d,
353
+		0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a,
354
+		0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783,
355
+	},
356
+	{
357
+		0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1,
358
+		0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf,
359
+		0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15,
360
+		0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121,
361
+		0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25,
362
+		0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5,
363
+		0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb,
364
+		0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5,
365
+		0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d,
366
+		0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6,
367
+		0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23,
368
+		0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003,
369
+		0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6,
370
+		0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119,
371
+		0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,
372
+		0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a,
373
+		0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79,
374
+		0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df,
375
+		0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26,
376
+		0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab,
377
+		0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7,
378
+		0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417,
379
+		0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2,
380
+		0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2,
381
+		0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a,
382
+		0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919,
383
+		0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef,
384
+		0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876,
385
+		0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab,
386
+		0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04,
387
+		0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282,
388
+		0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2,
389
+	},
390
+	{
391
+		0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f,
392
+		0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a,
393
+		0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff,
394
+		0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02,
395
+		0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a,
396
+		0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7,
397
+		0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9,
398
+		0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, 0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981,
399
+		0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774,
400
+		0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655,
401
+		0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, 0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2,
402
+		0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910,
403
+		0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1,
404
+		0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, 0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da,
405
+		0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049,
406
+		0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f,
407
+		0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, 0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba,
408
+		0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be,
409
+		0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3,
410
+		0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840,
411
+		0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4,
412
+		0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2,
413
+		0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, 0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7,
414
+		0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5,
415
+		0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e,
416
+		0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, 0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e,
417
+		0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801,
418
+		0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad,
419
+		0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0,
420
+		0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20,
421
+		0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8,
422
+		0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4,
423
+	},
424
+	{
425
+		0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac,
426
+		0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138,
427
+		0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367,
428
+		0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98,
429
+		0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072,
430
+		0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3,
431
+		0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd,
432
+		0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, 0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8,
433
+		0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9,
434
+		0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54,
435
+		0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, 0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387,
436
+		0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc,
437
+		0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf,
438
+		0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, 0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf,
439
+		0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f,
440
+		0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289,
441
+		0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, 0x20951063, 0x4576698d, 0xb6fad407, 0x592af950,
442
+		0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f,
443
+		0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b,
444
+		0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be,
445
+		0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13,
446
+		0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976,
447
+		0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0,
448
+		0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891,
449
+		0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da,
450
+		0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc,
451
+		0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084,
452
+		0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25,
453
+		0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121,
454
+		0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5,
455
+		0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd,
456
+		0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f,
457
+	},
458
+	{
459
+		0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f,
460
+		0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de,
461
+		0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43,
462
+		0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19,
463
+		0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2,
464
+		0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516,
465
+		0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88,
466
+		0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, 0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816,
467
+		0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756,
468
+		0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a,
469
+		0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, 0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264,
470
+		0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688,
471
+		0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28,
472
+		0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, 0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3,
473
+		0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7,
474
+		0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06,
475
+		0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033,
476
+		0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a,
477
+		0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566,
478
+		0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509,
479
+		0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962,
480
+		0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e,
481
+		0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, 0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c,
482
+		0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c,
483
+		0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285,
484
+		0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, 0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301,
485
+		0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be,
486
+		0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767,
487
+		0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647,
488
+		0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914,
489
+		0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c,
490
+		0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3,
491
+	},
492
+	{
493
+		0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5,
494
+		0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc,
495
+		0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd,
496
+		0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d,
497
+		0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2,
498
+		0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862,
499
+		0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc,
500
+		0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, 0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c,
501
+		0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e,
502
+		0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039,
503
+		0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, 0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8,
504
+		0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42,
505
+		0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5,
506
+		0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, 0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472,
507
+		0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225,
508
+		0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c,
509
+		0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, 0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb,
510
+		0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054,
511
+		0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70,
512
+		0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc,
513
+		0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c,
514
+		0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3,
515
+		0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, 0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4,
516
+		0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101,
517
+		0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f,
518
+		0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, 0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e,
519
+		0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a,
520
+		0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c,
521
+		0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384,
522
+		0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c,
523
+		0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82,
524
+		0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e,
525
+	},
526
+}

+ 106
- 0
vendor/src/golang.org/x/crypto/cast5/cast5_test.go 查看文件

@@ -0,0 +1,106 @@
1
+// Copyright 2010 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
+
5
+package cast5
6
+
7
+import (
8
+	"bytes"
9
+	"encoding/hex"
10
+	"testing"
11
+)
12
+
13
+// This test vector is taken from RFC 2144, App B.1.
14
+// Since the other two test vectors are for reduced-round variants, we can't
15
+// use them.
16
+var basicTests = []struct {
17
+	key, plainText, cipherText string
18
+}{
19
+	{
20
+		"0123456712345678234567893456789a",
21
+		"0123456789abcdef",
22
+		"238b4fe5847e44b2",
23
+	},
24
+}
25
+
26
+func TestBasic(t *testing.T) {
27
+	for i, test := range basicTests {
28
+		key, _ := hex.DecodeString(test.key)
29
+		plainText, _ := hex.DecodeString(test.plainText)
30
+		expected, _ := hex.DecodeString(test.cipherText)
31
+
32
+		c, err := NewCipher(key)
33
+		if err != nil {
34
+			t.Errorf("#%d: failed to create Cipher: %s", i, err)
35
+			continue
36
+		}
37
+		var cipherText [BlockSize]byte
38
+		c.Encrypt(cipherText[:], plainText)
39
+		if !bytes.Equal(cipherText[:], expected) {
40
+			t.Errorf("#%d: got:%x want:%x", i, cipherText, expected)
41
+		}
42
+
43
+		var plainTextAgain [BlockSize]byte
44
+		c.Decrypt(plainTextAgain[:], cipherText[:])
45
+		if !bytes.Equal(plainTextAgain[:], plainText) {
46
+			t.Errorf("#%d: got:%x want:%x", i, plainTextAgain, plainText)
47
+		}
48
+	}
49
+}
50
+
51
+// TestFull performs the test specified in RFC 2144, App B.2.
52
+// However, due to the length of time taken, it's disabled here and a more
53
+// limited version is included, below.
54
+func TestFull(t *testing.T) {
55
+	if testing.Short() {
56
+		// This is too slow for normal testing
57
+		return
58
+	}
59
+
60
+	a, b := iterate(1000000)
61
+
62
+	const expectedA = "eea9d0a249fd3ba6b3436fb89d6dca92"
63
+	const expectedB = "b2c95eb00c31ad7180ac05b8e83d696e"
64
+
65
+	if hex.EncodeToString(a) != expectedA {
66
+		t.Errorf("a: got:%x want:%s", a, expectedA)
67
+	}
68
+	if hex.EncodeToString(b) != expectedB {
69
+		t.Errorf("b: got:%x want:%s", b, expectedB)
70
+	}
71
+}
72
+
73
+func iterate(iterations int) ([]byte, []byte) {
74
+	const initValueHex = "0123456712345678234567893456789a"
75
+
76
+	initValue, _ := hex.DecodeString(initValueHex)
77
+
78
+	var a, b [16]byte
79
+	copy(a[:], initValue)
80
+	copy(b[:], initValue)
81
+
82
+	for i := 0; i < iterations; i++ {
83
+		c, _ := NewCipher(b[:])
84
+		c.Encrypt(a[:8], a[:8])
85
+		c.Encrypt(a[8:], a[8:])
86
+		c, _ = NewCipher(a[:])
87
+		c.Encrypt(b[:8], b[:8])
88
+		c.Encrypt(b[8:], b[8:])
89
+	}
90
+
91
+	return a[:], b[:]
92
+}
93
+
94
+func TestLimited(t *testing.T) {
95
+	a, b := iterate(1000)
96
+
97
+	const expectedA = "23f73b14b02a2ad7dfb9f2c35644798d"
98
+	const expectedB = "e5bf37eff14c456a40b21ce369370a9f"
99
+
100
+	if hex.EncodeToString(a) != expectedA {
101
+		t.Errorf("a: got:%x want:%s", a, expectedA)
102
+	}
103
+	if hex.EncodeToString(b) != expectedB {
104
+		t.Errorf("b: got:%x want:%s", b, expectedB)
105
+	}
106
+}

+ 219
- 0
vendor/src/golang.org/x/crypto/openpgp/armor/armor.go 查看文件

@@ -0,0 +1,219 @@
1
+// Copyright 2010 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
+
5
+// Package armor implements OpenPGP ASCII Armor, see RFC 4880. OpenPGP Armor is
6
+// very similar to PEM except that it has an additional CRC checksum.
7
+package armor // import "golang.org/x/crypto/openpgp/armor"
8
+
9
+import (
10
+	"bufio"
11
+	"bytes"
12
+	"encoding/base64"
13
+	"golang.org/x/crypto/openpgp/errors"
14
+	"io"
15
+)
16
+
17
+// A Block represents an OpenPGP armored structure.
18
+//
19
+// The encoded form is:
20
+//    -----BEGIN Type-----
21
+//    Headers
22
+//
23
+//    base64-encoded Bytes
24
+//    '=' base64 encoded checksum
25
+//    -----END Type-----
26
+// where Headers is a possibly empty sequence of Key: Value lines.
27
+//
28
+// Since the armored data can be very large, this package presents a streaming
29
+// interface.
30
+type Block struct {
31
+	Type    string            // The type, taken from the preamble (i.e. "PGP SIGNATURE").
32
+	Header  map[string]string // Optional headers.
33
+	Body    io.Reader         // A Reader from which the contents can be read
34
+	lReader lineReader
35
+	oReader openpgpReader
36
+}
37
+
38
+var ArmorCorrupt error = errors.StructuralError("armor invalid")
39
+
40
+const crc24Init = 0xb704ce
41
+const crc24Poly = 0x1864cfb
42
+const crc24Mask = 0xffffff
43
+
44
+// crc24 calculates the OpenPGP checksum as specified in RFC 4880, section 6.1
45
+func crc24(crc uint32, d []byte) uint32 {
46
+	for _, b := range d {
47
+		crc ^= uint32(b) << 16
48
+		for i := 0; i < 8; i++ {
49
+			crc <<= 1
50
+			if crc&0x1000000 != 0 {
51
+				crc ^= crc24Poly
52
+			}
53
+		}
54
+	}
55
+	return crc
56
+}
57
+
58
+var armorStart = []byte("-----BEGIN ")
59
+var armorEnd = []byte("-----END ")
60
+var armorEndOfLine = []byte("-----")
61
+
62
+// lineReader wraps a line based reader. It watches for the end of an armor
63
+// block and records the expected CRC value.
64
+type lineReader struct {
65
+	in  *bufio.Reader
66
+	buf []byte
67
+	eof bool
68
+	crc uint32
69
+}
70
+
71
+func (l *lineReader) Read(p []byte) (n int, err error) {
72
+	if l.eof {
73
+		return 0, io.EOF
74
+	}
75
+
76
+	if len(l.buf) > 0 {
77
+		n = copy(p, l.buf)
78
+		l.buf = l.buf[n:]
79
+		return
80
+	}
81
+
82
+	line, isPrefix, err := l.in.ReadLine()
83
+	if err != nil {
84
+		return
85
+	}
86
+	if isPrefix {
87
+		return 0, ArmorCorrupt
88
+	}
89
+
90
+	if len(line) == 5 && line[0] == '=' {
91
+		// This is the checksum line
92
+		var expectedBytes [3]byte
93
+		var m int
94
+		m, err = base64.StdEncoding.Decode(expectedBytes[0:], line[1:])
95
+		if m != 3 || err != nil {
96
+			return
97
+		}
98
+		l.crc = uint32(expectedBytes[0])<<16 |
99
+			uint32(expectedBytes[1])<<8 |
100
+			uint32(expectedBytes[2])
101
+
102
+		line, _, err = l.in.ReadLine()
103
+		if err != nil && err != io.EOF {
104
+			return
105
+		}
106
+		if !bytes.HasPrefix(line, armorEnd) {
107
+			return 0, ArmorCorrupt
108
+		}
109
+
110
+		l.eof = true
111
+		return 0, io.EOF
112
+	}
113
+
114
+	if len(line) > 96 {
115
+		return 0, ArmorCorrupt
116
+	}
117
+
118
+	n = copy(p, line)
119
+	bytesToSave := len(line) - n
120
+	if bytesToSave > 0 {
121
+		if cap(l.buf) < bytesToSave {
122
+			l.buf = make([]byte, 0, bytesToSave)
123
+		}
124
+		l.buf = l.buf[0:bytesToSave]
125
+		copy(l.buf, line[n:])
126
+	}
127
+
128
+	return
129
+}
130
+
131
+// openpgpReader passes Read calls to the underlying base64 decoder, but keeps
132
+// a running CRC of the resulting data and checks the CRC against the value
133
+// found by the lineReader at EOF.
134
+type openpgpReader struct {
135
+	lReader    *lineReader
136
+	b64Reader  io.Reader
137
+	currentCRC uint32
138
+}
139
+
140
+func (r *openpgpReader) Read(p []byte) (n int, err error) {
141
+	n, err = r.b64Reader.Read(p)
142
+	r.currentCRC = crc24(r.currentCRC, p[:n])
143
+
144
+	if err == io.EOF {
145
+		if r.lReader.crc != uint32(r.currentCRC&crc24Mask) {
146
+			return 0, ArmorCorrupt
147
+		}
148
+	}
149
+
150
+	return
151
+}
152
+
153
+// Decode reads a PGP armored block from the given Reader. It will ignore
154
+// leading garbage. If it doesn't find a block, it will return nil, io.EOF. The
155
+// given Reader is not usable after calling this function: an arbitrary amount
156
+// of data may have been read past the end of the block.
157
+func Decode(in io.Reader) (p *Block, err error) {
158
+	r := bufio.NewReaderSize(in, 100)
159
+	var line []byte
160
+	ignoreNext := false
161
+
162
+TryNextBlock:
163
+	p = nil
164
+
165
+	// Skip leading garbage
166
+	for {
167
+		ignoreThis := ignoreNext
168
+		line, ignoreNext, err = r.ReadLine()
169
+		if err != nil {
170
+			return
171
+		}
172
+		if ignoreNext || ignoreThis {
173
+			continue
174
+		}
175
+		line = bytes.TrimSpace(line)
176
+		if len(line) > len(armorStart)+len(armorEndOfLine) && bytes.HasPrefix(line, armorStart) {
177
+			break
178
+		}
179
+	}
180
+
181
+	p = new(Block)
182
+	p.Type = string(line[len(armorStart) : len(line)-len(armorEndOfLine)])
183
+	p.Header = make(map[string]string)
184
+	nextIsContinuation := false
185
+	var lastKey string
186
+
187
+	// Read headers
188
+	for {
189
+		isContinuation := nextIsContinuation
190
+		line, nextIsContinuation, err = r.ReadLine()
191
+		if err != nil {
192
+			p = nil
193
+			return
194
+		}
195
+		if isContinuation {
196
+			p.Header[lastKey] += string(line)
197
+			continue
198
+		}
199
+		line = bytes.TrimSpace(line)
200
+		if len(line) == 0 {
201
+			break
202
+		}
203
+
204
+		i := bytes.Index(line, []byte(": "))
205
+		if i == -1 {
206
+			goto TryNextBlock
207
+		}
208
+		lastKey = string(line[:i])
209
+		p.Header[lastKey] = string(line[i+2:])
210
+	}
211
+
212
+	p.lReader.in = r
213
+	p.oReader.currentCRC = crc24Init
214
+	p.oReader.lReader = &p.lReader
215
+	p.oReader.b64Reader = base64.NewDecoder(base64.StdEncoding, &p.lReader)
216
+	p.Body = &p.oReader
217
+
218
+	return
219
+}

+ 95
- 0
vendor/src/golang.org/x/crypto/openpgp/armor/armor_test.go 查看文件

@@ -0,0 +1,95 @@
1
+// Copyright 2010 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
+
5
+package armor
6
+
7
+import (
8
+	"bytes"
9
+	"hash/adler32"
10
+	"io/ioutil"
11
+	"testing"
12
+)
13
+
14
+func TestDecodeEncode(t *testing.T) {
15
+	buf := bytes.NewBuffer([]byte(armorExample1))
16
+	result, err := Decode(buf)
17
+	if err != nil {
18
+		t.Error(err)
19
+	}
20
+	expectedType := "PGP SIGNATURE"
21
+	if result.Type != expectedType {
22
+		t.Errorf("result.Type: got:%s want:%s", result.Type, expectedType)
23
+	}
24
+	if len(result.Header) != 1 {
25
+		t.Errorf("len(result.Header): got:%d want:1", len(result.Header))
26
+	}
27
+	v, ok := result.Header["Version"]
28
+	if !ok || v != "GnuPG v1.4.10 (GNU/Linux)" {
29
+		t.Errorf("result.Header: got:%#v", result.Header)
30
+	}
31
+
32
+	contents, err := ioutil.ReadAll(result.Body)
33
+	if err != nil {
34
+		t.Error(err)
35
+	}
36
+
37
+	if adler32.Checksum(contents) != 0x27b144be {
38
+		t.Errorf("contents: got: %x", contents)
39
+	}
40
+
41
+	buf = bytes.NewBuffer(nil)
42
+	w, err := Encode(buf, result.Type, result.Header)
43
+	if err != nil {
44
+		t.Error(err)
45
+	}
46
+	_, err = w.Write(contents)
47
+	if err != nil {
48
+		t.Error(err)
49
+	}
50
+	w.Close()
51
+
52
+	if !bytes.Equal(buf.Bytes(), []byte(armorExample1)) {
53
+		t.Errorf("got: %s\nwant: %s", string(buf.Bytes()), armorExample1)
54
+	}
55
+}
56
+
57
+func TestLongHeader(t *testing.T) {
58
+	buf := bytes.NewBuffer([]byte(armorLongLine))
59
+	result, err := Decode(buf)
60
+	if err != nil {
61
+		t.Error(err)
62
+		return
63
+	}
64
+	value, ok := result.Header["Version"]
65
+	if !ok {
66
+		t.Errorf("missing Version header")
67
+	}
68
+	if value != longValueExpected {
69
+		t.Errorf("got: %s want: %s", value, longValueExpected)
70
+	}
71
+}
72
+
73
+const armorExample1 = `-----BEGIN PGP SIGNATURE-----
74
+Version: GnuPG v1.4.10 (GNU/Linux)
75
+
76
+iJwEAAECAAYFAk1Fv/0ACgkQo01+GMIMMbsYTwQAiAw+QAaNfY6WBdplZ/uMAccm
77
+4g+81QPmTSGHnetSb6WBiY13kVzK4HQiZH8JSkmmroMLuGeJwsRTEL4wbjRyUKEt
78
+p1xwUZDECs234F1xiG5enc5SGlRtP7foLBz9lOsjx+LEcA4sTl5/2eZR9zyFZqWW
79
+TxRjs+fJCIFuo71xb1g=
80
+=/teI
81
+-----END PGP SIGNATURE-----`
82
+
83
+const armorLongLine = `-----BEGIN PGP SIGNATURE-----
84
+Version: 0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz
85
+
86
+iQEcBAABAgAGBQJMtFESAAoJEKsQXJGvOPsVj40H/1WW6jaMXv4BW+1ueDSMDwM8
87
+kx1fLOXbVM5/Kn5LStZNt1jWWnpxdz7eq3uiqeCQjmqUoRde3YbB2EMnnwRbAhpp
88
+cacnAvy9ZQ78OTxUdNW1mhX5bS6q1MTEJnl+DcyigD70HG/yNNQD7sOPMdYQw0TA
89
+byQBwmLwmTsuZsrYqB68QyLHI+DUugn+kX6Hd2WDB62DKa2suoIUIHQQCd/ofwB3
90
+WfCYInXQKKOSxu2YOg2Eb4kLNhSMc1i9uKUWAH+sdgJh7NBgdoE4MaNtBFkHXRvv
91
+okWuf3+xA9ksp1npSY/mDvgHijmjvtpRDe6iUeqfCn8N9u9CBg8geANgaG8+QA4=
92
+=wfQG
93
+-----END PGP SIGNATURE-----`
94
+
95
+const longValueExpected = "0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz"

+ 160
- 0
vendor/src/golang.org/x/crypto/openpgp/armor/encode.go 查看文件

@@ -0,0 +1,160 @@
1
+// Copyright 2010 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
+
5
+package armor
6
+
7
+import (
8
+	"encoding/base64"
9
+	"io"
10
+)
11
+
12
+var armorHeaderSep = []byte(": ")
13
+var blockEnd = []byte("\n=")
14
+var newline = []byte("\n")
15
+var armorEndOfLineOut = []byte("-----\n")
16
+
17
+// writeSlices writes its arguments to the given Writer.
18
+func writeSlices(out io.Writer, slices ...[]byte) (err error) {
19
+	for _, s := range slices {
20
+		_, err = out.Write(s)
21
+		if err != nil {
22
+			return err
23
+		}
24
+	}
25
+	return
26
+}
27
+
28
+// lineBreaker breaks data across several lines, all of the same byte length
29
+// (except possibly the last). Lines are broken with a single '\n'.
30
+type lineBreaker struct {
31
+	lineLength  int
32
+	line        []byte
33
+	used        int
34
+	out         io.Writer
35
+	haveWritten bool
36
+}
37
+
38
+func newLineBreaker(out io.Writer, lineLength int) *lineBreaker {
39
+	return &lineBreaker{
40
+		lineLength: lineLength,
41
+		line:       make([]byte, lineLength),
42
+		used:       0,
43
+		out:        out,
44
+	}
45
+}
46
+
47
+func (l *lineBreaker) Write(b []byte) (n int, err error) {
48
+	n = len(b)
49
+
50
+	if n == 0 {
51
+		return
52
+	}
53
+
54
+	if l.used == 0 && l.haveWritten {
55
+		_, err = l.out.Write([]byte{'\n'})
56
+		if err != nil {
57
+			return
58
+		}
59
+	}
60
+
61
+	if l.used+len(b) < l.lineLength {
62
+		l.used += copy(l.line[l.used:], b)
63
+		return
64
+	}
65
+
66
+	l.haveWritten = true
67
+	_, err = l.out.Write(l.line[0:l.used])
68
+	if err != nil {
69
+		return
70
+	}
71
+	excess := l.lineLength - l.used
72
+	l.used = 0
73
+
74
+	_, err = l.out.Write(b[0:excess])
75
+	if err != nil {
76
+		return
77
+	}
78
+
79
+	_, err = l.Write(b[excess:])
80
+	return
81
+}
82
+
83
+func (l *lineBreaker) Close() (err error) {
84
+	if l.used > 0 {
85
+		_, err = l.out.Write(l.line[0:l.used])
86
+		if err != nil {
87
+			return
88
+		}
89
+	}
90
+
91
+	return
92
+}
93
+
94
+// encoding keeps track of a running CRC24 over the data which has been written
95
+// to it and outputs a OpenPGP checksum when closed, followed by an armor
96
+// trailer.
97
+//
98
+// It's built into a stack of io.Writers:
99
+//    encoding -> base64 encoder -> lineBreaker -> out
100
+type encoding struct {
101
+	out       io.Writer
102
+	breaker   *lineBreaker
103
+	b64       io.WriteCloser
104
+	crc       uint32
105
+	blockType []byte
106
+}
107
+
108
+func (e *encoding) Write(data []byte) (n int, err error) {
109
+	e.crc = crc24(e.crc, data)
110
+	return e.b64.Write(data)
111
+}
112
+
113
+func (e *encoding) Close() (err error) {
114
+	err = e.b64.Close()
115
+	if err != nil {
116
+		return
117
+	}
118
+	e.breaker.Close()
119
+
120
+	var checksumBytes [3]byte
121
+	checksumBytes[0] = byte(e.crc >> 16)
122
+	checksumBytes[1] = byte(e.crc >> 8)
123
+	checksumBytes[2] = byte(e.crc)
124
+
125
+	var b64ChecksumBytes [4]byte
126
+	base64.StdEncoding.Encode(b64ChecksumBytes[:], checksumBytes[:])
127
+
128
+	return writeSlices(e.out, blockEnd, b64ChecksumBytes[:], newline, armorEnd, e.blockType, armorEndOfLine)
129
+}
130
+
131
+// Encode returns a WriteCloser which will encode the data written to it in
132
+// OpenPGP armor.
133
+func Encode(out io.Writer, blockType string, headers map[string]string) (w io.WriteCloser, err error) {
134
+	bType := []byte(blockType)
135
+	err = writeSlices(out, armorStart, bType, armorEndOfLineOut)
136
+	if err != nil {
137
+		return
138
+	}
139
+
140
+	for k, v := range headers {
141
+		err = writeSlices(out, []byte(k), armorHeaderSep, []byte(v), newline)
142
+		if err != nil {
143
+			return
144
+		}
145
+	}
146
+
147
+	_, err = out.Write(newline)
148
+	if err != nil {
149
+		return
150
+	}
151
+
152
+	e := &encoding{
153
+		out:       out,
154
+		breaker:   newLineBreaker(out, 64),
155
+		crc:       crc24Init,
156
+		blockType: bType,
157
+	}
158
+	e.b64 = base64.NewEncoder(base64.StdEncoding, e.breaker)
159
+	return e, nil
160
+}

+ 59
- 0
vendor/src/golang.org/x/crypto/openpgp/canonical_text.go 查看文件

@@ -0,0 +1,59 @@
1
+// Copyright 2011 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
+
5
+package openpgp
6
+
7
+import "hash"
8
+
9
+// NewCanonicalTextHash reformats text written to it into the canonical
10
+// form and then applies the hash h.  See RFC 4880, section 5.2.1.
11
+func NewCanonicalTextHash(h hash.Hash) hash.Hash {
12
+	return &canonicalTextHash{h, 0}
13
+}
14
+
15
+type canonicalTextHash struct {
16
+	h hash.Hash
17
+	s int
18
+}
19
+
20
+var newline = []byte{'\r', '\n'}
21
+
22
+func (cth *canonicalTextHash) Write(buf []byte) (int, error) {
23
+	start := 0
24
+
25
+	for i, c := range buf {
26
+		switch cth.s {
27
+		case 0:
28
+			if c == '\r' {
29
+				cth.s = 1
30
+			} else if c == '\n' {
31
+				cth.h.Write(buf[start:i])
32
+				cth.h.Write(newline)
33
+				start = i + 1
34
+			}
35
+		case 1:
36
+			cth.s = 0
37
+		}
38
+	}
39
+
40
+	cth.h.Write(buf[start:])
41
+	return len(buf), nil
42
+}
43
+
44
+func (cth *canonicalTextHash) Sum(in []byte) []byte {
45
+	return cth.h.Sum(in)
46
+}
47
+
48
+func (cth *canonicalTextHash) Reset() {
49
+	cth.h.Reset()
50
+	cth.s = 0
51
+}
52
+
53
+func (cth *canonicalTextHash) Size() int {
54
+	return cth.h.Size()
55
+}
56
+
57
+func (cth *canonicalTextHash) BlockSize() int {
58
+	return cth.h.BlockSize()
59
+}

+ 52
- 0
vendor/src/golang.org/x/crypto/openpgp/canonical_text_test.go 查看文件

@@ -0,0 +1,52 @@
1
+// Copyright 2011 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
+
5
+package openpgp
6
+
7
+import (
8
+	"bytes"
9
+	"testing"
10
+)
11
+
12
+type recordingHash struct {
13
+	buf *bytes.Buffer
14
+}
15
+
16
+func (r recordingHash) Write(b []byte) (n int, err error) {
17
+	return r.buf.Write(b)
18
+}
19
+
20
+func (r recordingHash) Sum(in []byte) []byte {
21
+	return append(in, r.buf.Bytes()...)
22
+}
23
+
24
+func (r recordingHash) Reset() {
25
+	panic("shouldn't be called")
26
+}
27
+
28
+func (r recordingHash) Size() int {
29
+	panic("shouldn't be called")
30
+}
31
+
32
+func (r recordingHash) BlockSize() int {
33
+	panic("shouldn't be called")
34
+}
35
+
36
+func testCanonicalText(t *testing.T, input, expected string) {
37
+	r := recordingHash{bytes.NewBuffer(nil)}
38
+	c := NewCanonicalTextHash(r)
39
+	c.Write([]byte(input))
40
+	result := c.Sum(nil)
41
+	if expected != string(result) {
42
+		t.Errorf("input: %x got: %x want: %x", input, result, expected)
43
+	}
44
+}
45
+
46
+func TestCanonicalText(t *testing.T) {
47
+	testCanonicalText(t, "foo\n", "foo\r\n")
48
+	testCanonicalText(t, "foo", "foo")
49
+	testCanonicalText(t, "foo\r\n", "foo\r\n")
50
+	testCanonicalText(t, "foo\r\nbar", "foo\r\nbar")
51
+	testCanonicalText(t, "foo\r\nbar\n\n", "foo\r\nbar\r\n\r\n")
52
+}

+ 376
- 0
vendor/src/golang.org/x/crypto/openpgp/clearsign/clearsign.go 查看文件

@@ -0,0 +1,376 @@
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
+
5
+// Package clearsign generates and processes OpenPGP, clear-signed data. See
6
+// RFC 4880, section 7.
7
+//
8
+// Clearsigned messages are cryptographically signed, but the contents of the
9
+// message are kept in plaintext so that it can be read without special tools.
10
+package clearsign // import "golang.org/x/crypto/openpgp/clearsign"
11
+
12
+import (
13
+	"bufio"
14
+	"bytes"
15
+	"crypto"
16
+	"hash"
17
+	"io"
18
+	"net/textproto"
19
+	"strconv"
20
+
21
+	"golang.org/x/crypto/openpgp/armor"
22
+	"golang.org/x/crypto/openpgp/errors"
23
+	"golang.org/x/crypto/openpgp/packet"
24
+)
25
+
26
+// A Block represents a clearsigned message. A signature on a Block can
27
+// be checked by passing Bytes into openpgp.CheckDetachedSignature.
28
+type Block struct {
29
+	Headers          textproto.MIMEHeader // Optional message headers
30
+	Plaintext        []byte               // The original message text
31
+	Bytes            []byte               // The signed message
32
+	ArmoredSignature *armor.Block         // The signature block
33
+}
34
+
35
+// start is the marker which denotes the beginning of a clearsigned message.
36
+var start = []byte("\n-----BEGIN PGP SIGNED MESSAGE-----")
37
+
38
+// dashEscape is prefixed to any lines that begin with a hyphen so that they
39
+// can't be confused with endText.
40
+var dashEscape = []byte("- ")
41
+
42
+// endText is a marker which denotes the end of the message and the start of
43
+// an armored signature.
44
+var endText = []byte("-----BEGIN PGP SIGNATURE-----")
45
+
46
+// end is a marker which denotes the end of the armored signature.
47
+var end = []byte("\n-----END PGP SIGNATURE-----")
48
+
49
+var crlf = []byte("\r\n")
50
+var lf = byte('\n')
51
+
52
+// getLine returns the first \r\n or \n delineated line from the given byte
53
+// array. The line does not include the \r\n or \n. The remainder of the byte
54
+// array (also not including the new line bytes) is also returned and this will
55
+// always be smaller than the original argument.
56
+func getLine(data []byte) (line, rest []byte) {
57
+	i := bytes.Index(data, []byte{'\n'})
58
+	var j int
59
+	if i < 0 {
60
+		i = len(data)
61
+		j = i
62
+	} else {
63
+		j = i + 1
64
+		if i > 0 && data[i-1] == '\r' {
65
+			i--
66
+		}
67
+	}
68
+	return data[0:i], data[j:]
69
+}
70
+
71
+// Decode finds the first clearsigned message in data and returns it, as well
72
+// as the suffix of data which remains after the message.
73
+func Decode(data []byte) (b *Block, rest []byte) {
74
+	// start begins with a newline. However, at the very beginning of
75
+	// the byte array, we'll accept the start string without it.
76
+	rest = data
77
+	if bytes.HasPrefix(data, start[1:]) {
78
+		rest = rest[len(start)-1:]
79
+	} else if i := bytes.Index(data, start); i >= 0 {
80
+		rest = rest[i+len(start):]
81
+	} else {
82
+		return nil, data
83
+	}
84
+
85
+	// Consume the start line.
86
+	_, rest = getLine(rest)
87
+
88
+	var line []byte
89
+	b = &Block{
90
+		Headers: make(textproto.MIMEHeader),
91
+	}
92
+
93
+	// Next come a series of header lines.
94
+	for {
95
+		// This loop terminates because getLine's second result is
96
+		// always smaller than its argument.
97
+		if len(rest) == 0 {
98
+			return nil, data
99
+		}
100
+		// An empty line marks the end of the headers.
101
+		if line, rest = getLine(rest); len(line) == 0 {
102
+			break
103
+		}
104
+
105
+		i := bytes.Index(line, []byte{':'})
106
+		if i == -1 {
107
+			return nil, data
108
+		}
109
+
110
+		key, val := line[0:i], line[i+1:]
111
+		key = bytes.TrimSpace(key)
112
+		val = bytes.TrimSpace(val)
113
+		b.Headers.Add(string(key), string(val))
114
+	}
115
+
116
+	firstLine := true
117
+	for {
118
+		start := rest
119
+
120
+		line, rest = getLine(rest)
121
+		if len(line) == 0 && len(rest) == 0 {
122
+			// No armored data was found, so this isn't a complete message.
123
+			return nil, data
124
+		}
125
+		if bytes.Equal(line, endText) {
126
+			// Back up to the start of the line because armor expects to see the
127
+			// header line.
128
+			rest = start
129
+			break
130
+		}
131
+
132
+		// The final CRLF isn't included in the hash so we don't write it until
133
+		// we've seen the next line.
134
+		if firstLine {
135
+			firstLine = false
136
+		} else {
137
+			b.Bytes = append(b.Bytes, crlf...)
138
+		}
139
+
140
+		if bytes.HasPrefix(line, dashEscape) {
141
+			line = line[2:]
142
+		}
143
+		line = bytes.TrimRight(line, " \t")
144
+		b.Bytes = append(b.Bytes, line...)
145
+
146
+		b.Plaintext = append(b.Plaintext, line...)
147
+		b.Plaintext = append(b.Plaintext, lf)
148
+	}
149
+
150
+	// We want to find the extent of the armored data (including any newlines at
151
+	// the end).
152
+	i := bytes.Index(rest, end)
153
+	if i == -1 {
154
+		return nil, data
155
+	}
156
+	i += len(end)
157
+	for i < len(rest) && (rest[i] == '\r' || rest[i] == '\n') {
158
+		i++
159
+	}
160
+	armored := rest[:i]
161
+	rest = rest[i:]
162
+
163
+	var err error
164
+	b.ArmoredSignature, err = armor.Decode(bytes.NewBuffer(armored))
165
+	if err != nil {
166
+		return nil, data
167
+	}
168
+
169
+	return b, rest
170
+}
171
+
172
+// A dashEscaper is an io.WriteCloser which processes the body of a clear-signed
173
+// message. The clear-signed message is written to buffered and a hash, suitable
174
+// for signing, is maintained in h.
175
+//
176
+// When closed, an armored signature is created and written to complete the
177
+// message.
178
+type dashEscaper struct {
179
+	buffered *bufio.Writer
180
+	h        hash.Hash
181
+	hashType crypto.Hash
182
+
183
+	atBeginningOfLine bool
184
+	isFirstLine       bool
185
+
186
+	whitespace []byte
187
+	byteBuf    []byte // a one byte buffer to save allocations
188
+
189
+	privateKey *packet.PrivateKey
190
+	config     *packet.Config
191
+}
192
+
193
+func (d *dashEscaper) Write(data []byte) (n int, err error) {
194
+	for _, b := range data {
195
+		d.byteBuf[0] = b
196
+
197
+		if d.atBeginningOfLine {
198
+			// The final CRLF isn't included in the hash so we have to wait
199
+			// until this point (the start of the next line) before writing it.
200
+			if !d.isFirstLine {
201
+				d.h.Write(crlf)
202
+			}
203
+			d.isFirstLine = false
204
+		}
205
+
206
+		// Any whitespace at the end of the line has to be removed so we
207
+		// buffer it until we find out whether there's more on this line.
208
+		if b == ' ' || b == '\t' || b == '\r' {
209
+			d.whitespace = append(d.whitespace, b)
210
+			d.atBeginningOfLine = false
211
+			continue
212
+		}
213
+
214
+		if d.atBeginningOfLine {
215
+			// At the beginning of a line, hyphens have to be escaped.
216
+			if b == '-' {
217
+				// The signature isn't calculated over the dash-escaped text so
218
+				// the escape is only written to buffered.
219
+				if _, err = d.buffered.Write(dashEscape); err != nil {
220
+					return
221
+				}
222
+				d.h.Write(d.byteBuf)
223
+				d.atBeginningOfLine = false
224
+			} else if b == '\n' {
225
+				// Nothing to do because we delay writing CRLF to the hash.
226
+			} else {
227
+				d.h.Write(d.byteBuf)
228
+				d.atBeginningOfLine = false
229
+			}
230
+			if err = d.buffered.WriteByte(b); err != nil {
231
+				return
232
+			}
233
+		} else {
234
+			if b == '\n' {
235
+				// We got a raw \n. Drop any trailing whitespace and write a
236
+				// CRLF.
237
+				d.whitespace = d.whitespace[:0]
238
+				// We delay writing CRLF to the hash until the start of the
239
+				// next line.
240
+				if err = d.buffered.WriteByte(b); err != nil {
241
+					return
242
+				}
243
+				d.atBeginningOfLine = true
244
+			} else {
245
+				// Any buffered whitespace wasn't at the end of the line so
246
+				// we need to write it out.
247
+				if len(d.whitespace) > 0 {
248
+					d.h.Write(d.whitespace)
249
+					if _, err = d.buffered.Write(d.whitespace); err != nil {
250
+						return
251
+					}
252
+					d.whitespace = d.whitespace[:0]
253
+				}
254
+				d.h.Write(d.byteBuf)
255
+				if err = d.buffered.WriteByte(b); err != nil {
256
+					return
257
+				}
258
+			}
259
+		}
260
+	}
261
+
262
+	n = len(data)
263
+	return
264
+}
265
+
266
+func (d *dashEscaper) Close() (err error) {
267
+	if !d.atBeginningOfLine {
268
+		if err = d.buffered.WriteByte(lf); err != nil {
269
+			return
270
+		}
271
+	}
272
+	sig := new(packet.Signature)
273
+	sig.SigType = packet.SigTypeText
274
+	sig.PubKeyAlgo = d.privateKey.PubKeyAlgo
275
+	sig.Hash = d.hashType
276
+	sig.CreationTime = d.config.Now()
277
+	sig.IssuerKeyId = &d.privateKey.KeyId
278
+
279
+	if err = sig.Sign(d.h, d.privateKey, d.config); err != nil {
280
+		return
281
+	}
282
+
283
+	out, err := armor.Encode(d.buffered, "PGP SIGNATURE", nil)
284
+	if err != nil {
285
+		return
286
+	}
287
+
288
+	if err = sig.Serialize(out); err != nil {
289
+		return
290
+	}
291
+	if err = out.Close(); err != nil {
292
+		return
293
+	}
294
+	if err = d.buffered.Flush(); err != nil {
295
+		return
296
+	}
297
+	return
298
+}
299
+
300
+// Encode returns a WriteCloser which will clear-sign a message with privateKey
301
+// and write it to w. If config is nil, sensible defaults are used.
302
+func Encode(w io.Writer, privateKey *packet.PrivateKey, config *packet.Config) (plaintext io.WriteCloser, err error) {
303
+	if privateKey.Encrypted {
304
+		return nil, errors.InvalidArgumentError("signing key is encrypted")
305
+	}
306
+
307
+	hashType := config.Hash()
308
+	name := nameOfHash(hashType)
309
+	if len(name) == 0 {
310
+		return nil, errors.UnsupportedError("unknown hash type: " + strconv.Itoa(int(hashType)))
311
+	}
312
+
313
+	if !hashType.Available() {
314
+		return nil, errors.UnsupportedError("unsupported hash type: " + strconv.Itoa(int(hashType)))
315
+	}
316
+	h := hashType.New()
317
+
318
+	buffered := bufio.NewWriter(w)
319
+	// start has a \n at the beginning that we don't want here.
320
+	if _, err = buffered.Write(start[1:]); err != nil {
321
+		return
322
+	}
323
+	if err = buffered.WriteByte(lf); err != nil {
324
+		return
325
+	}
326
+	if _, err = buffered.WriteString("Hash: "); err != nil {
327
+		return
328
+	}
329
+	if _, err = buffered.WriteString(name); err != nil {
330
+		return
331
+	}
332
+	if err = buffered.WriteByte(lf); err != nil {
333
+		return
334
+	}
335
+	if err = buffered.WriteByte(lf); err != nil {
336
+		return
337
+	}
338
+
339
+	plaintext = &dashEscaper{
340
+		buffered: buffered,
341
+		h:        h,
342
+		hashType: hashType,
343
+
344
+		atBeginningOfLine: true,
345
+		isFirstLine:       true,
346
+
347
+		byteBuf: make([]byte, 1),
348
+
349
+		privateKey: privateKey,
350
+		config:     config,
351
+	}
352
+
353
+	return
354
+}
355
+
356
+// nameOfHash returns the OpenPGP name for the given hash, or the empty string
357
+// if the name isn't known. See RFC 4880, section 9.4.
358
+func nameOfHash(h crypto.Hash) string {
359
+	switch h {
360
+	case crypto.MD5:
361
+		return "MD5"
362
+	case crypto.SHA1:
363
+		return "SHA1"
364
+	case crypto.RIPEMD160:
365
+		return "RIPEMD160"
366
+	case crypto.SHA224:
367
+		return "SHA224"
368
+	case crypto.SHA256:
369
+		return "SHA256"
370
+	case crypto.SHA384:
371
+		return "SHA384"
372
+	case crypto.SHA512:
373
+		return "SHA512"
374
+	}
375
+	return ""
376
+}

+ 210
- 0
vendor/src/golang.org/x/crypto/openpgp/clearsign/clearsign_test.go 查看文件

@@ -0,0 +1,210 @@
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
+
5
+package clearsign
6
+
7
+import (
8
+	"bytes"
9
+	"golang.org/x/crypto/openpgp"
10
+	"testing"
11
+)
12
+
13
+func testParse(t *testing.T, input []byte, expected, expectedPlaintext string) {
14
+	b, rest := Decode(input)
15
+	if b == nil {
16
+		t.Fatal("failed to decode clearsign message")
17
+	}
18
+	if !bytes.Equal(rest, []byte("trailing")) {
19
+		t.Errorf("unexpected remaining bytes returned: %s", string(rest))
20
+	}
21
+	if b.ArmoredSignature.Type != "PGP SIGNATURE" {
22
+		t.Errorf("bad armor type, got:%s, want:PGP SIGNATURE", b.ArmoredSignature.Type)
23
+	}
24
+	if !bytes.Equal(b.Bytes, []byte(expected)) {
25
+		t.Errorf("bad body, got:%x want:%x", b.Bytes, expected)
26
+	}
27
+
28
+	if !bytes.Equal(b.Plaintext, []byte(expectedPlaintext)) {
29
+		t.Errorf("bad plaintext, got:%x want:%x", b.Plaintext, expectedPlaintext)
30
+	}
31
+
32
+	keyring, err := openpgp.ReadArmoredKeyRing(bytes.NewBufferString(signingKey))
33
+	if err != nil {
34
+		t.Errorf("failed to parse public key: %s", err)
35
+	}
36
+
37
+	if _, err := openpgp.CheckDetachedSignature(keyring, bytes.NewBuffer(b.Bytes), b.ArmoredSignature.Body); err != nil {
38
+		t.Errorf("failed to check signature: %s", err)
39
+	}
40
+}
41
+
42
+func TestParse(t *testing.T) {
43
+	testParse(t, clearsignInput, "Hello world\r\nline 2", "Hello world\nline 2\n")
44
+	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")
45
+}
46
+
47
+func TestParseInvalid(t *testing.T) {
48
+	if b, _ := Decode(clearsignInput3); b != nil {
49
+		t.Fatal("decoded a bad clearsigned message without any error")
50
+	}
51
+}
52
+
53
+func TestParseWithNoNewlineAtEnd(t *testing.T) {
54
+	input := clearsignInput
55
+	input = input[:len(input)-len("trailing")-1]
56
+	b, rest := Decode(input)
57
+	if b == nil {
58
+		t.Fatal("failed to decode clearsign message")
59
+	}
60
+	if len(rest) > 0 {
61
+		t.Errorf("unexpected remaining bytes returned: %s", string(rest))
62
+	}
63
+}
64
+
65
+var signingTests = []struct {
66
+	in, signed, plaintext string
67
+}{
68
+	{"", "", ""},
69
+	{"a", "a", "a\n"},
70
+	{"a\n", "a", "a\n"},
71
+	{"-a\n", "-a", "-a\n"},
72
+	{"--a\nb", "--a\r\nb", "--a\nb\n"},
73
+	// leading whitespace
74
+	{" a\n", " a", " a\n"},
75
+	{"  a\n", "  a", "  a\n"},
76
+	// trailing whitespace (should be stripped)
77
+	{"a \n", "a", "a\n"},
78
+	{"a ", "a", "a\n"},
79
+	// whitespace-only lines (should be stripped)
80
+	{"  \n", "", "\n"},
81
+	{"  ", "", "\n"},
82
+	{"a\n  \n  \nb\n", "a\r\n\r\n\r\nb", "a\n\n\nb\n"},
83
+}
84
+
85
+func TestSigning(t *testing.T) {
86
+	keyring, err := openpgp.ReadArmoredKeyRing(bytes.NewBufferString(signingKey))
87
+	if err != nil {
88
+		t.Errorf("failed to parse public key: %s", err)
89
+	}
90
+
91
+	for i, test := range signingTests {
92
+		var buf bytes.Buffer
93
+
94
+		plaintext, err := Encode(&buf, keyring[0].PrivateKey, nil)
95
+		if err != nil {
96
+			t.Errorf("#%d: error from Encode: %s", i, err)
97
+			continue
98
+		}
99
+		if _, err := plaintext.Write([]byte(test.in)); err != nil {
100
+			t.Errorf("#%d: error from Write: %s", i, err)
101
+			continue
102
+		}
103
+		if err := plaintext.Close(); err != nil {
104
+			t.Fatalf("#%d: error from Close: %s", i, err)
105
+			continue
106
+		}
107
+
108
+		b, _ := Decode(buf.Bytes())
109
+		if b == nil {
110
+			t.Errorf("#%d: failed to decode clearsign message", i)
111
+			continue
112
+		}
113
+		if !bytes.Equal(b.Bytes, []byte(test.signed)) {
114
+			t.Errorf("#%d: bad result, got:%x, want:%x", i, b.Bytes, test.signed)
115
+			continue
116
+		}
117
+		if !bytes.Equal(b.Plaintext, []byte(test.plaintext)) {
118
+			t.Errorf("#%d: bad result, got:%x, want:%x", i, b.Plaintext, test.plaintext)
119
+			continue
120
+		}
121
+
122
+		if _, err := openpgp.CheckDetachedSignature(keyring, bytes.NewBuffer(b.Bytes), b.ArmoredSignature.Body); err != nil {
123
+			t.Errorf("#%d: failed to check signature: %s", i, err)
124
+		}
125
+	}
126
+}
127
+
128
+var clearsignInput = []byte(`
129
+;lasjlkfdsa
130
+
131
+-----BEGIN PGP SIGNED MESSAGE-----
132
+Hash: SHA1
133
+
134
+Hello world
135
+line 2
136
+-----BEGIN PGP SIGNATURE-----
137
+Version: GnuPG v1.4.10 (GNU/Linux)
138
+
139
+iJwEAQECAAYFAk8kMuEACgkQO9o98PRieSpMsAQAhmY/vwmNpflrPgmfWsYhk5O8
140
+pjnBUzZwqTDoDeINjZEoPDSpQAHGhjFjgaDx/Gj4fAl0dM4D0wuUEBb6QOrwflog
141
+2A2k9kfSOMOtk0IH/H5VuFN1Mie9L/erYXjTQIptv9t9J7NoRBMU0QOOaFU0JaO9
142
+MyTpno24AjIAGb+mH1U=
143
+=hIJ6
144
+-----END PGP SIGNATURE-----
145
+trailing`)
146
+
147
+var clearsignInput2 = []byte(`
148
+asdlfkjasdlkfjsadf
149
+
150
+-----BEGIN PGP SIGNED MESSAGE-----
151
+Hash: SHA256
152
+
153
+
154
+
155
+(This message has a couple of blank lines at the start and end.)
156
+
157
+
158
+-----BEGIN PGP SIGNATURE-----
159
+Version: GnuPG v1.4.11 (GNU/Linux)
160
+
161
+iJwEAQEIAAYFAlPpSREACgkQO9o98PRieSpZTAP+M8QUoCt/7Rf3YbXPcdzIL32v
162
+pt1I+cMNeopzfLy0u4ioEFi8s5VkwpL1AFmirvgViCwlf82inoRxzZRiW05JQ5LI
163
+ESEzeCoy2LIdRCQ2hcrG8pIUPzUO4TqO5D/dMbdHwNH4h5nNmGJUAEG6FpURlPm+
164
+qZg6BaTvOxepqOxnhVU=
165
+=e+C6
166
+-----END PGP SIGNATURE-----
167
+
168
+trailing`)
169
+
170
+var clearsignInput3 = []byte(`
171
+-----BEGIN PGP SIGNED MESSAGE-----
172
+Hash: SHA256
173
+
174
+(This message was truncated.)
175
+`)
176
+
177
+var signingKey = `-----BEGIN PGP PRIVATE KEY BLOCK-----
178
+Version: GnuPG v1.4.10 (GNU/Linux)
179
+
180
+lQHYBE2rFNoBBADFwqWQIW/DSqcB4yCQqnAFTJ27qS5AnB46ccAdw3u4Greeu3Bp
181
+idpoHdjULy7zSKlwR1EA873dO/k/e11Ml3dlAFUinWeejWaK2ugFP6JjiieSsrKn
182
+vWNicdCS4HTWn0X4sjl0ZiAygw6GNhqEQ3cpLeL0g8E9hnYzJKQ0LWJa0QARAQAB
183
+AAP/TB81EIo2VYNmTq0pK1ZXwUpxCrvAAIG3hwKjEzHcbQznsjNvPUihZ+NZQ6+X
184
+0HCfPAdPkGDCLCb6NavcSW+iNnLTrdDnSI6+3BbIONqWWdRDYJhqZCkqmG6zqSfL
185
+IdkJgCw94taUg5BWP/AAeQrhzjChvpMQTVKQL5mnuZbUCeMCAN5qrYMP2S9iKdnk
186
+VANIFj7656ARKt/nf4CBzxcpHTyB8+d2CtPDKCmlJP6vL8t58Jmih+kHJMvC0dzn
187
+gr5f5+sCAOOe5gt9e0am7AvQWhdbHVfJU0TQJx+m2OiCJAqGTB1nvtBLHdJnfdC9
188
+TnXXQ6ZXibqLyBies/xeY2sCKL5qtTMCAKnX9+9d/5yQxRyrQUHt1NYhaXZnJbHx
189
+q4ytu0eWz+5i68IYUSK69jJ1NWPM0T6SkqpB3KCAIv68VFm9PxqG1KmhSrQIVGVz
190
+dCBLZXmIuAQTAQIAIgUCTasU2gIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AA
191
+CgkQO9o98PRieSoLhgQAkLEZex02Qt7vGhZzMwuN0R22w3VwyYyjBx+fM3JFETy1
192
+ut4xcLJoJfIaF5ZS38UplgakHG0FQ+b49i8dMij0aZmDqGxrew1m4kBfjXw9B/v+
193
+eIqpODryb6cOSwyQFH0lQkXC040pjq9YqDsO5w0WYNXYKDnzRV0p4H1pweo2VDid
194
+AdgETasU2gEEAN46UPeWRqKHvA99arOxee38fBt2CI08iiWyI8T3J6ivtFGixSqV
195
+bRcPxYO/qLpVe5l84Nb3X71GfVXlc9hyv7CD6tcowL59hg1E/DC5ydI8K8iEpUmK
196
+/UnHdIY5h8/kqgGxkY/T/hgp5fRQgW1ZoZxLajVlMRZ8W4tFtT0DeA+JABEBAAEA
197
+A/0bE1jaaZKj6ndqcw86jd+QtD1SF+Cf21CWRNeLKnUds4FRRvclzTyUMuWPkUeX
198
+TaNNsUOFqBsf6QQ2oHUBBK4VCHffHCW4ZEX2cd6umz7mpHW6XzN4DECEzOVksXtc
199
+lUC1j4UB91DC/RNQqwX1IV2QLSwssVotPMPqhOi0ZLNY7wIA3n7DWKInxYZZ4K+6
200
+rQ+POsz6brEoRHwr8x6XlHenq1Oki855pSa1yXIARoTrSJkBtn5oI+f8AzrnN0BN
201
+oyeQAwIA/7E++3HDi5aweWrViiul9cd3rcsS0dEnksPhvS0ozCJiHsq/6GFmy7J8
202
+QSHZPteedBnZyNp5jR+H7cIfVN3KgwH/Skq4PsuPhDq5TKK6i8Pc1WW8MA6DXTdU
203
+nLkX7RGmMwjC0DBf7KWAlPjFaONAX3a8ndnz//fy1q7u2l9AZwrj1qa1iJ8EGAEC
204
+AAkFAk2rFNoCGwwACgkQO9o98PRieSo2/QP/WTzr4ioINVsvN1akKuekmEMI3LAp
205
+BfHwatufxxP1U+3Si/6YIk7kuPB9Hs+pRqCXzbvPRrI8NHZBmc8qIGthishdCYad
206
+AHcVnXjtxrULkQFGbGvhKURLvS9WnzD/m1K2zzwxzkPTzT9/Yf06O6Mal5AdugPL
207
+VrM0m72/jnpKo04=
208
+=zNCn
209
+-----END PGP PRIVATE KEY BLOCK-----
210
+`

+ 122
- 0
vendor/src/golang.org/x/crypto/openpgp/elgamal/elgamal.go 查看文件

@@ -0,0 +1,122 @@
1
+// Copyright 2011 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
+
5
+// Package elgamal implements ElGamal encryption, suitable for OpenPGP,
6
+// as specified in "A Public-Key Cryptosystem and a Signature Scheme Based on
7
+// Discrete Logarithms," IEEE Transactions on Information Theory, v. IT-31,
8
+// n. 4, 1985, pp. 469-472.
9
+//
10
+// This form of ElGamal embeds PKCS#1 v1.5 padding, which may make it
11
+// unsuitable for other protocols. RSA should be used in preference in any
12
+// case.
13
+package elgamal // import "golang.org/x/crypto/openpgp/elgamal"
14
+
15
+import (
16
+	"crypto/rand"
17
+	"crypto/subtle"
18
+	"errors"
19
+	"io"
20
+	"math/big"
21
+)
22
+
23
+// PublicKey represents an ElGamal public key.
24
+type PublicKey struct {
25
+	G, P, Y *big.Int
26
+}
27
+
28
+// PrivateKey represents an ElGamal private key.
29
+type PrivateKey struct {
30
+	PublicKey
31
+	X *big.Int
32
+}
33
+
34
+// Encrypt encrypts the given message to the given public key. The result is a
35
+// pair of integers. Errors can result from reading random, or because msg is
36
+// too large to be encrypted to the public key.
37
+func Encrypt(random io.Reader, pub *PublicKey, msg []byte) (c1, c2 *big.Int, err error) {
38
+	pLen := (pub.P.BitLen() + 7) / 8
39
+	if len(msg) > pLen-11 {
40
+		err = errors.New("elgamal: message too long")
41
+		return
42
+	}
43
+
44
+	// EM = 0x02 || PS || 0x00 || M
45
+	em := make([]byte, pLen-1)
46
+	em[0] = 2
47
+	ps, mm := em[1:len(em)-len(msg)-1], em[len(em)-len(msg):]
48
+	err = nonZeroRandomBytes(ps, random)
49
+	if err != nil {
50
+		return
51
+	}
52
+	em[len(em)-len(msg)-1] = 0
53
+	copy(mm, msg)
54
+
55
+	m := new(big.Int).SetBytes(em)
56
+
57
+	k, err := rand.Int(random, pub.P)
58
+	if err != nil {
59
+		return
60
+	}
61
+
62
+	c1 = new(big.Int).Exp(pub.G, k, pub.P)
63
+	s := new(big.Int).Exp(pub.Y, k, pub.P)
64
+	c2 = s.Mul(s, m)
65
+	c2.Mod(c2, pub.P)
66
+
67
+	return
68
+}
69
+
70
+// Decrypt takes two integers, resulting from an ElGamal encryption, and
71
+// returns the plaintext of the message. An error can result only if the
72
+// ciphertext is invalid. Users should keep in mind that this is a padding
73
+// oracle and thus, if exposed to an adaptive chosen ciphertext attack, can
74
+// be used to break the cryptosystem.  See ``Chosen Ciphertext Attacks
75
+// Against Protocols Based on the RSA Encryption Standard PKCS #1'', Daniel
76
+// Bleichenbacher, Advances in Cryptology (Crypto '98),
77
+func Decrypt(priv *PrivateKey, c1, c2 *big.Int) (msg []byte, err error) {
78
+	s := new(big.Int).Exp(c1, priv.X, priv.P)
79
+	s.ModInverse(s, priv.P)
80
+	s.Mul(s, c2)
81
+	s.Mod(s, priv.P)
82
+	em := s.Bytes()
83
+
84
+	firstByteIsTwo := subtle.ConstantTimeByteEq(em[0], 2)
85
+
86
+	// The remainder of the plaintext must be a string of non-zero random
87
+	// octets, followed by a 0, followed by the message.
88
+	//   lookingForIndex: 1 iff we are still looking for the zero.
89
+	//   index: the offset of the first zero byte.
90
+	var lookingForIndex, index int
91
+	lookingForIndex = 1
92
+
93
+	for i := 1; i < len(em); i++ {
94
+		equals0 := subtle.ConstantTimeByteEq(em[i], 0)
95
+		index = subtle.ConstantTimeSelect(lookingForIndex&equals0, i, index)
96
+		lookingForIndex = subtle.ConstantTimeSelect(equals0, 0, lookingForIndex)
97
+	}
98
+
99
+	if firstByteIsTwo != 1 || lookingForIndex != 0 || index < 9 {
100
+		return nil, errors.New("elgamal: decryption error")
101
+	}
102
+	return em[index+1:], nil
103
+}
104
+
105
+// nonZeroRandomBytes fills the given slice with non-zero random octets.
106
+func nonZeroRandomBytes(s []byte, rand io.Reader) (err error) {
107
+	_, err = io.ReadFull(rand, s)
108
+	if err != nil {
109
+		return
110
+	}
111
+
112
+	for i := 0; i < len(s); i++ {
113
+		for s[i] == 0 {
114
+			_, err = io.ReadFull(rand, s[i:i+1])
115
+			if err != nil {
116
+				return
117
+			}
118
+		}
119
+	}
120
+
121
+	return
122
+}

+ 49
- 0
vendor/src/golang.org/x/crypto/openpgp/elgamal/elgamal_test.go 查看文件

@@ -0,0 +1,49 @@
1
+// Copyright 2011 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
+
5
+package elgamal
6
+
7
+import (
8
+	"bytes"
9
+	"crypto/rand"
10
+	"math/big"
11
+	"testing"
12
+)
13
+
14
+// This is the 1024-bit MODP group from RFC 5114, section 2.1:
15
+const primeHex = "B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C69A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C013ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD7098488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708DF1FB2BC2E4A4371"
16
+
17
+const generatorHex = "A4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507FD6406CFF14266D31266FEA1E5C41564B777E690F5504F213160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28AD662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24855E6EEB22B3B2E5"
18
+
19
+func fromHex(hex string) *big.Int {
20
+	n, ok := new(big.Int).SetString(hex, 16)
21
+	if !ok {
22
+		panic("failed to parse hex number")
23
+	}
24
+	return n
25
+}
26
+
27
+func TestEncryptDecrypt(t *testing.T) {
28
+	priv := &PrivateKey{
29
+		PublicKey: PublicKey{
30
+			G: fromHex(generatorHex),
31
+			P: fromHex(primeHex),
32
+		},
33
+		X: fromHex("42"),
34
+	}
35
+	priv.Y = new(big.Int).Exp(priv.G, priv.X, priv.P)
36
+
37
+	message := []byte("hello world")
38
+	c1, c2, err := Encrypt(rand.Reader, &priv.PublicKey, message)
39
+	if err != nil {
40
+		t.Errorf("error encrypting: %s", err)
41
+	}
42
+	message2, err := Decrypt(priv, c1, c2)
43
+	if err != nil {
44
+		t.Errorf("error decrypting: %s", err)
45
+	}
46
+	if !bytes.Equal(message2, message) {
47
+		t.Errorf("decryption failed, got: %x, want: %x", message2, message)
48
+	}
49
+}

+ 72
- 0
vendor/src/golang.org/x/crypto/openpgp/errors/errors.go 查看文件

@@ -0,0 +1,72 @@
1
+// Copyright 2010 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
+
5
+// Package errors contains common error types for the OpenPGP packages.
6
+package errors // import "golang.org/x/crypto/openpgp/errors"
7
+
8
+import (
9
+	"strconv"
10
+)
11
+
12
+// A StructuralError is returned when OpenPGP data is found to be syntactically
13
+// invalid.
14
+type StructuralError string
15
+
16
+func (s StructuralError) Error() string {
17
+	return "openpgp: invalid data: " + string(s)
18
+}
19
+
20
+// UnsupportedError indicates that, although the OpenPGP data is valid, it
21
+// makes use of currently unimplemented features.
22
+type UnsupportedError string
23
+
24
+func (s UnsupportedError) Error() string {
25
+	return "openpgp: unsupported feature: " + string(s)
26
+}
27
+
28
+// InvalidArgumentError indicates that the caller is in error and passed an
29
+// incorrect value.
30
+type InvalidArgumentError string
31
+
32
+func (i InvalidArgumentError) Error() string {
33
+	return "openpgp: invalid argument: " + string(i)
34
+}
35
+
36
+// SignatureError indicates that a syntactically valid signature failed to
37
+// validate.
38
+type SignatureError string
39
+
40
+func (b SignatureError) Error() string {
41
+	return "openpgp: invalid signature: " + string(b)
42
+}
43
+
44
+type keyIncorrectError int
45
+
46
+func (ki keyIncorrectError) Error() string {
47
+	return "openpgp: incorrect key"
48
+}
49
+
50
+var ErrKeyIncorrect error = keyIncorrectError(0)
51
+
52
+type unknownIssuerError int
53
+
54
+func (unknownIssuerError) Error() string {
55
+	return "openpgp: signature made by unknown entity"
56
+}
57
+
58
+var ErrUnknownIssuer error = unknownIssuerError(0)
59
+
60
+type keyRevokedError int
61
+
62
+func (keyRevokedError) Error() string {
63
+	return "openpgp: signature made by revoked key"
64
+}
65
+
66
+var ErrKeyRevoked error = keyRevokedError(0)
67
+
68
+type UnknownPacketTypeError uint8
69
+
70
+func (upte UnknownPacketTypeError) Error() string {
71
+	return "openpgp: unknown packet type: " + strconv.Itoa(int(upte))
72
+}

+ 636
- 0
vendor/src/golang.org/x/crypto/openpgp/keys.go 查看文件

@@ -0,0 +1,636 @@
1
+// Copyright 2011 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
+
5
+package openpgp
6
+
7
+import (
8
+	"crypto/rsa"
9
+	"io"
10
+	"time"
11
+
12
+	"golang.org/x/crypto/openpgp/armor"
13
+	"golang.org/x/crypto/openpgp/errors"
14
+	"golang.org/x/crypto/openpgp/packet"
15
+)
16
+
17
+// PublicKeyType is the armor type for a PGP public key.
18
+var PublicKeyType = "PGP PUBLIC KEY BLOCK"
19
+
20
+// PrivateKeyType is the armor type for a PGP private key.
21
+var PrivateKeyType = "PGP PRIVATE KEY BLOCK"
22
+
23
+// An Entity represents the components of an OpenPGP key: a primary public key
24
+// (which must be a signing key), one or more identities claimed by that key,
25
+// and zero or more subkeys, which may be encryption keys.
26
+type Entity struct {
27
+	PrimaryKey  *packet.PublicKey
28
+	PrivateKey  *packet.PrivateKey
29
+	Identities  map[string]*Identity // indexed by Identity.Name
30
+	Revocations []*packet.Signature
31
+	Subkeys     []Subkey
32
+}
33
+
34
+// An Identity represents an identity claimed by an Entity and zero or more
35
+// assertions by other entities about that claim.
36
+type Identity struct {
37
+	Name          string // by convention, has the form "Full Name (comment) <email@example.com>"
38
+	UserId        *packet.UserId
39
+	SelfSignature *packet.Signature
40
+	Signatures    []*packet.Signature
41
+}
42
+
43
+// A Subkey is an additional public key in an Entity. Subkeys can be used for
44
+// encryption.
45
+type Subkey struct {
46
+	PublicKey  *packet.PublicKey
47
+	PrivateKey *packet.PrivateKey
48
+	Sig        *packet.Signature
49
+}
50
+
51
+// A Key identifies a specific public key in an Entity. This is either the
52
+// Entity's primary key or a subkey.
53
+type Key struct {
54
+	Entity        *Entity
55
+	PublicKey     *packet.PublicKey
56
+	PrivateKey    *packet.PrivateKey
57
+	SelfSignature *packet.Signature
58
+}
59
+
60
+// A KeyRing provides access to public and private keys.
61
+type KeyRing interface {
62
+	// KeysById returns the set of keys that have the given key id.
63
+	KeysById(id uint64) []Key
64
+	// KeysByIdAndUsage returns the set of keys with the given id
65
+	// that also meet the key usage given by requiredUsage.
66
+	// The requiredUsage is expressed as the bitwise-OR of
67
+	// packet.KeyFlag* values.
68
+	KeysByIdUsage(id uint64, requiredUsage byte) []Key
69
+	// DecryptionKeys returns all private keys that are valid for
70
+	// decryption.
71
+	DecryptionKeys() []Key
72
+}
73
+
74
+// primaryIdentity returns the Identity marked as primary or the first identity
75
+// if none are so marked.
76
+func (e *Entity) primaryIdentity() *Identity {
77
+	var firstIdentity *Identity
78
+	for _, ident := range e.Identities {
79
+		if firstIdentity == nil {
80
+			firstIdentity = ident
81
+		}
82
+		if ident.SelfSignature.IsPrimaryId != nil && *ident.SelfSignature.IsPrimaryId {
83
+			return ident
84
+		}
85
+	}
86
+	return firstIdentity
87
+}
88
+
89
+// encryptionKey returns the best candidate Key for encrypting a message to the
90
+// given Entity.
91
+func (e *Entity) encryptionKey(now time.Time) (Key, bool) {
92
+	candidateSubkey := -1
93
+
94
+	// Iterate the keys to find the newest key
95
+	var maxTime time.Time
96
+	for i, subkey := range e.Subkeys {
97
+		if subkey.Sig.FlagsValid &&
98
+			subkey.Sig.FlagEncryptCommunications &&
99
+			subkey.PublicKey.PubKeyAlgo.CanEncrypt() &&
100
+			!subkey.Sig.KeyExpired(now) &&
101
+			(maxTime.IsZero() || subkey.Sig.CreationTime.After(maxTime)) {
102
+			candidateSubkey = i
103
+			maxTime = subkey.Sig.CreationTime
104
+		}
105
+	}
106
+
107
+	if candidateSubkey != -1 {
108
+		subkey := e.Subkeys[candidateSubkey]
109
+		return Key{e, subkey.PublicKey, subkey.PrivateKey, subkey.Sig}, true
110
+	}
111
+
112
+	// If we don't have any candidate subkeys for encryption and
113
+	// the primary key doesn't have any usage metadata then we
114
+	// assume that the primary key is ok. Or, if the primary key is
115
+	// marked as ok to encrypt to, then we can obviously use it.
116
+	i := e.primaryIdentity()
117
+	if !i.SelfSignature.FlagsValid || i.SelfSignature.FlagEncryptCommunications &&
118
+		e.PrimaryKey.PubKeyAlgo.CanEncrypt() &&
119
+		!i.SelfSignature.KeyExpired(now) {
120
+		return Key{e, e.PrimaryKey, e.PrivateKey, i.SelfSignature}, true
121
+	}
122
+
123
+	// This Entity appears to be signing only.
124
+	return Key{}, false
125
+}
126
+
127
+// signingKey return the best candidate Key for signing a message with this
128
+// Entity.
129
+func (e *Entity) signingKey(now time.Time) (Key, bool) {
130
+	candidateSubkey := -1
131
+
132
+	for i, subkey := range e.Subkeys {
133
+		if subkey.Sig.FlagsValid &&
134
+			subkey.Sig.FlagSign &&
135
+			subkey.PublicKey.PubKeyAlgo.CanSign() &&
136
+			!subkey.Sig.KeyExpired(now) {
137
+			candidateSubkey = i
138
+			break
139
+		}
140
+	}
141
+
142
+	if candidateSubkey != -1 {
143
+		subkey := e.Subkeys[candidateSubkey]
144
+		return Key{e, subkey.PublicKey, subkey.PrivateKey, subkey.Sig}, true
145
+	}
146
+
147
+	// If we have no candidate subkey then we assume that it's ok to sign
148
+	// with the primary key.
149
+	i := e.primaryIdentity()
150
+	if !i.SelfSignature.FlagsValid || i.SelfSignature.FlagSign &&
151
+		!i.SelfSignature.KeyExpired(now) {
152
+		return Key{e, e.PrimaryKey, e.PrivateKey, i.SelfSignature}, true
153
+	}
154
+
155
+	return Key{}, false
156
+}
157
+
158
+// An EntityList contains one or more Entities.
159
+type EntityList []*Entity
160
+
161
+// KeysById returns the set of keys that have the given key id.
162
+func (el EntityList) KeysById(id uint64) (keys []Key) {
163
+	for _, e := range el {
164
+		if e.PrimaryKey.KeyId == id {
165
+			var selfSig *packet.Signature
166
+			for _, ident := range e.Identities {
167
+				if selfSig == nil {
168
+					selfSig = ident.SelfSignature
169
+				} else if ident.SelfSignature.IsPrimaryId != nil && *ident.SelfSignature.IsPrimaryId {
170
+					selfSig = ident.SelfSignature
171
+					break
172
+				}
173
+			}
174
+			keys = append(keys, Key{e, e.PrimaryKey, e.PrivateKey, selfSig})
175
+		}
176
+
177
+		for _, subKey := range e.Subkeys {
178
+			if subKey.PublicKey.KeyId == id {
179
+				keys = append(keys, Key{e, subKey.PublicKey, subKey.PrivateKey, subKey.Sig})
180
+			}
181
+		}
182
+	}
183
+	return
184
+}
185
+
186
+// KeysByIdAndUsage returns the set of keys with the given id that also meet
187
+// the key usage given by requiredUsage.  The requiredUsage is expressed as
188
+// the bitwise-OR of packet.KeyFlag* values.
189
+func (el EntityList) KeysByIdUsage(id uint64, requiredUsage byte) (keys []Key) {
190
+	for _, key := range el.KeysById(id) {
191
+		if len(key.Entity.Revocations) > 0 {
192
+			continue
193
+		}
194
+
195
+		if key.SelfSignature.RevocationReason != nil {
196
+			continue
197
+		}
198
+
199
+		if key.SelfSignature.FlagsValid && requiredUsage != 0 {
200
+			var usage byte
201
+			if key.SelfSignature.FlagCertify {
202
+				usage |= packet.KeyFlagCertify
203
+			}
204
+			if key.SelfSignature.FlagSign {
205
+				usage |= packet.KeyFlagSign
206
+			}
207
+			if key.SelfSignature.FlagEncryptCommunications {
208
+				usage |= packet.KeyFlagEncryptCommunications
209
+			}
210
+			if key.SelfSignature.FlagEncryptStorage {
211
+				usage |= packet.KeyFlagEncryptStorage
212
+			}
213
+			if usage&requiredUsage != requiredUsage {
214
+				continue
215
+			}
216
+		}
217
+
218
+		keys = append(keys, key)
219
+	}
220
+	return
221
+}
222
+
223
+// DecryptionKeys returns all private keys that are valid for decryption.
224
+func (el EntityList) DecryptionKeys() (keys []Key) {
225
+	for _, e := range el {
226
+		for _, subKey := range e.Subkeys {
227
+			if subKey.PrivateKey != nil && (!subKey.Sig.FlagsValid || subKey.Sig.FlagEncryptStorage || subKey.Sig.FlagEncryptCommunications) {
228
+				keys = append(keys, Key{e, subKey.PublicKey, subKey.PrivateKey, subKey.Sig})
229
+			}
230
+		}
231
+	}
232
+	return
233
+}
234
+
235
+// ReadArmoredKeyRing reads one or more public/private keys from an armor keyring file.
236
+func ReadArmoredKeyRing(r io.Reader) (EntityList, error) {
237
+	block, err := armor.Decode(r)
238
+	if err == io.EOF {
239
+		return nil, errors.InvalidArgumentError("no armored data found")
240
+	}
241
+	if err != nil {
242
+		return nil, err
243
+	}
244
+	if block.Type != PublicKeyType && block.Type != PrivateKeyType {
245
+		return nil, errors.InvalidArgumentError("expected public or private key block, got: " + block.Type)
246
+	}
247
+
248
+	return ReadKeyRing(block.Body)
249
+}
250
+
251
+// ReadKeyRing reads one or more public/private keys. Unsupported keys are
252
+// ignored as long as at least a single valid key is found.
253
+func ReadKeyRing(r io.Reader) (el EntityList, err error) {
254
+	packets := packet.NewReader(r)
255
+	var lastUnsupportedError error
256
+
257
+	for {
258
+		var e *Entity
259
+		e, err = ReadEntity(packets)
260
+		if err != nil {
261
+			// TODO: warn about skipped unsupported/unreadable keys
262
+			if _, ok := err.(errors.UnsupportedError); ok {
263
+				lastUnsupportedError = err
264
+				err = readToNextPublicKey(packets)
265
+			} else if _, ok := err.(errors.StructuralError); ok {
266
+				// Skip unreadable, badly-formatted keys
267
+				lastUnsupportedError = err
268
+				err = readToNextPublicKey(packets)
269
+			}
270
+			if err == io.EOF {
271
+				err = nil
272
+				break
273
+			}
274
+			if err != nil {
275
+				el = nil
276
+				break
277
+			}
278
+		} else {
279
+			el = append(el, e)
280
+		}
281
+	}
282
+
283
+	if len(el) == 0 && err == nil {
284
+		err = lastUnsupportedError
285
+	}
286
+	return
287
+}
288
+
289
+// readToNextPublicKey reads packets until the start of the entity and leaves
290
+// the first packet of the new entity in the Reader.
291
+func readToNextPublicKey(packets *packet.Reader) (err error) {
292
+	var p packet.Packet
293
+	for {
294
+		p, err = packets.Next()
295
+		if err == io.EOF {
296
+			return
297
+		} else if err != nil {
298
+			if _, ok := err.(errors.UnsupportedError); ok {
299
+				err = nil
300
+				continue
301
+			}
302
+			return
303
+		}
304
+
305
+		if pk, ok := p.(*packet.PublicKey); ok && !pk.IsSubkey {
306
+			packets.Unread(p)
307
+			return
308
+		}
309
+	}
310
+}
311
+
312
+// ReadEntity reads an entity (public key, identities, subkeys etc) from the
313
+// given Reader.
314
+func ReadEntity(packets *packet.Reader) (*Entity, error) {
315
+	e := new(Entity)
316
+	e.Identities = make(map[string]*Identity)
317
+
318
+	p, err := packets.Next()
319
+	if err != nil {
320
+		return nil, err
321
+	}
322
+
323
+	var ok bool
324
+	if e.PrimaryKey, ok = p.(*packet.PublicKey); !ok {
325
+		if e.PrivateKey, ok = p.(*packet.PrivateKey); !ok {
326
+			packets.Unread(p)
327
+			return nil, errors.StructuralError("first packet was not a public/private key")
328
+		}
329
+		e.PrimaryKey = &e.PrivateKey.PublicKey
330
+	}
331
+
332
+	if !e.PrimaryKey.PubKeyAlgo.CanSign() {
333
+		return nil, errors.StructuralError("primary key cannot be used for signatures")
334
+	}
335
+
336
+	var current *Identity
337
+	var revocations []*packet.Signature
338
+EachPacket:
339
+	for {
340
+		p, err := packets.Next()
341
+		if err == io.EOF {
342
+			break
343
+		} else if err != nil {
344
+			return nil, err
345
+		}
346
+
347
+		switch pkt := p.(type) {
348
+		case *packet.UserId:
349
+			current = new(Identity)
350
+			current.Name = pkt.Id
351
+			current.UserId = pkt
352
+			e.Identities[pkt.Id] = current
353
+
354
+			for {
355
+				p, err = packets.Next()
356
+				if err == io.EOF {
357
+					return nil, io.ErrUnexpectedEOF
358
+				} else if err != nil {
359
+					return nil, err
360
+				}
361
+
362
+				sig, ok := p.(*packet.Signature)
363
+				if !ok {
364
+					return nil, errors.StructuralError("user ID packet not followed by self-signature")
365
+				}
366
+
367
+				if (sig.SigType == packet.SigTypePositiveCert || sig.SigType == packet.SigTypeGenericCert) && sig.IssuerKeyId != nil && *sig.IssuerKeyId == e.PrimaryKey.KeyId {
368
+					if err = e.PrimaryKey.VerifyUserIdSignature(pkt.Id, e.PrimaryKey, sig); err != nil {
369
+						return nil, errors.StructuralError("user ID self-signature invalid: " + err.Error())
370
+					}
371
+					current.SelfSignature = sig
372
+					break
373
+				}
374
+				current.Signatures = append(current.Signatures, sig)
375
+			}
376
+		case *packet.Signature:
377
+			if pkt.SigType == packet.SigTypeKeyRevocation {
378
+				revocations = append(revocations, pkt)
379
+			} else if pkt.SigType == packet.SigTypeDirectSignature {
380
+				// TODO: RFC4880 5.2.1 permits signatures
381
+				// directly on keys (eg. to bind additional
382
+				// revocation keys).
383
+			} else if current == nil {
384
+				return nil, errors.StructuralError("signature packet found before user id packet")
385
+			} else {
386
+				current.Signatures = append(current.Signatures, pkt)
387
+			}
388
+		case *packet.PrivateKey:
389
+			if pkt.IsSubkey == false {
390
+				packets.Unread(p)
391
+				break EachPacket
392
+			}
393
+			err = addSubkey(e, packets, &pkt.PublicKey, pkt)
394
+			if err != nil {
395
+				return nil, err
396
+			}
397
+		case *packet.PublicKey:
398
+			if pkt.IsSubkey == false {
399
+				packets.Unread(p)
400
+				break EachPacket
401
+			}
402
+			err = addSubkey(e, packets, pkt, nil)
403
+			if err != nil {
404
+				return nil, err
405
+			}
406
+		default:
407
+			// we ignore unknown packets
408
+		}
409
+	}
410
+
411
+	if len(e.Identities) == 0 {
412
+		return nil, errors.StructuralError("entity without any identities")
413
+	}
414
+
415
+	for _, revocation := range revocations {
416
+		err = e.PrimaryKey.VerifyRevocationSignature(revocation)
417
+		if err == nil {
418
+			e.Revocations = append(e.Revocations, revocation)
419
+		} else {
420
+			// TODO: RFC 4880 5.2.3.15 defines revocation keys.
421
+			return nil, errors.StructuralError("revocation signature signed by alternate key")
422
+		}
423
+	}
424
+
425
+	return e, nil
426
+}
427
+
428
+func addSubkey(e *Entity, packets *packet.Reader, pub *packet.PublicKey, priv *packet.PrivateKey) error {
429
+	var subKey Subkey
430
+	subKey.PublicKey = pub
431
+	subKey.PrivateKey = priv
432
+	p, err := packets.Next()
433
+	if err == io.EOF {
434
+		return io.ErrUnexpectedEOF
435
+	}
436
+	if err != nil {
437
+		return errors.StructuralError("subkey signature invalid: " + err.Error())
438
+	}
439
+	var ok bool
440
+	subKey.Sig, ok = p.(*packet.Signature)
441
+	if !ok {
442
+		return errors.StructuralError("subkey packet not followed by signature")
443
+	}
444
+	if subKey.Sig.SigType != packet.SigTypeSubkeyBinding && subKey.Sig.SigType != packet.SigTypeSubkeyRevocation {
445
+		return errors.StructuralError("subkey signature with wrong type")
446
+	}
447
+	err = e.PrimaryKey.VerifyKeySignature(subKey.PublicKey, subKey.Sig)
448
+	if err != nil {
449
+		return errors.StructuralError("subkey signature invalid: " + err.Error())
450
+	}
451
+	e.Subkeys = append(e.Subkeys, subKey)
452
+	return nil
453
+}
454
+
455
+const defaultRSAKeyBits = 2048
456
+
457
+// NewEntity returns an Entity that contains a fresh RSA/RSA keypair with a
458
+// single identity composed of the given full name, comment and email, any of
459
+// which may be empty but must not contain any of "()<>\x00".
460
+// If config is nil, sensible defaults will be used.
461
+func NewEntity(name, comment, email string, config *packet.Config) (*Entity, error) {
462
+	currentTime := config.Now()
463
+
464
+	bits := defaultRSAKeyBits
465
+	if config != nil && config.RSABits != 0 {
466
+		bits = config.RSABits
467
+	}
468
+
469
+	uid := packet.NewUserId(name, comment, email)
470
+	if uid == nil {
471
+		return nil, errors.InvalidArgumentError("user id field contained invalid characters")
472
+	}
473
+	signingPriv, err := rsa.GenerateKey(config.Random(), bits)
474
+	if err != nil {
475
+		return nil, err
476
+	}
477
+	encryptingPriv, err := rsa.GenerateKey(config.Random(), bits)
478
+	if err != nil {
479
+		return nil, err
480
+	}
481
+
482
+	e := &Entity{
483
+		PrimaryKey: packet.NewRSAPublicKey(currentTime, &signingPriv.PublicKey),
484
+		PrivateKey: packet.NewRSAPrivateKey(currentTime, signingPriv),
485
+		Identities: make(map[string]*Identity),
486
+	}
487
+	isPrimaryId := true
488
+	e.Identities[uid.Id] = &Identity{
489
+		Name:   uid.Name,
490
+		UserId: uid,
491
+		SelfSignature: &packet.Signature{
492
+			CreationTime: currentTime,
493
+			SigType:      packet.SigTypePositiveCert,
494
+			PubKeyAlgo:   packet.PubKeyAlgoRSA,
495
+			Hash:         config.Hash(),
496
+			IsPrimaryId:  &isPrimaryId,
497
+			FlagsValid:   true,
498
+			FlagSign:     true,
499
+			FlagCertify:  true,
500
+			IssuerKeyId:  &e.PrimaryKey.KeyId,
501
+		},
502
+	}
503
+
504
+	// If the user passes in a DefaultHash via packet.Config,
505
+	// set the PreferredHash for the SelfSignature.
506
+	if config != nil && config.DefaultHash != 0 {
507
+		e.Identities[uid.Id].SelfSignature.PreferredHash = []uint8{hashToHashId(config.DefaultHash)}
508
+	}
509
+
510
+	e.Subkeys = make([]Subkey, 1)
511
+	e.Subkeys[0] = Subkey{
512
+		PublicKey:  packet.NewRSAPublicKey(currentTime, &encryptingPriv.PublicKey),
513
+		PrivateKey: packet.NewRSAPrivateKey(currentTime, encryptingPriv),
514
+		Sig: &packet.Signature{
515
+			CreationTime:              currentTime,
516
+			SigType:                   packet.SigTypeSubkeyBinding,
517
+			PubKeyAlgo:                packet.PubKeyAlgoRSA,
518
+			Hash:                      config.Hash(),
519
+			FlagsValid:                true,
520
+			FlagEncryptStorage:        true,
521
+			FlagEncryptCommunications: true,
522
+			IssuerKeyId:               &e.PrimaryKey.KeyId,
523
+		},
524
+	}
525
+	e.Subkeys[0].PublicKey.IsSubkey = true
526
+	e.Subkeys[0].PrivateKey.IsSubkey = true
527
+
528
+	return e, nil
529
+}
530
+
531
+// SerializePrivate serializes an Entity, including private key material, to
532
+// the given Writer. For now, it must only be used on an Entity returned from
533
+// NewEntity.
534
+// If config is nil, sensible defaults will be used.
535
+func (e *Entity) SerializePrivate(w io.Writer, config *packet.Config) (err error) {
536
+	err = e.PrivateKey.Serialize(w)
537
+	if err != nil {
538
+		return
539
+	}
540
+	for _, ident := range e.Identities {
541
+		err = ident.UserId.Serialize(w)
542
+		if err != nil {
543
+			return
544
+		}
545
+		err = ident.SelfSignature.SignUserId(ident.UserId.Id, e.PrimaryKey, e.PrivateKey, config)
546
+		if err != nil {
547
+			return
548
+		}
549
+		err = ident.SelfSignature.Serialize(w)
550
+		if err != nil {
551
+			return
552
+		}
553
+	}
554
+	for _, subkey := range e.Subkeys {
555
+		err = subkey.PrivateKey.Serialize(w)
556
+		if err != nil {
557
+			return
558
+		}
559
+		err = subkey.Sig.SignKey(subkey.PublicKey, e.PrivateKey, config)
560
+		if err != nil {
561
+			return
562
+		}
563
+		err = subkey.Sig.Serialize(w)
564
+		if err != nil {
565
+			return
566
+		}
567
+	}
568
+	return nil
569
+}
570
+
571
+// Serialize writes the public part of the given Entity to w. (No private
572
+// key material will be output).
573
+func (e *Entity) Serialize(w io.Writer) error {
574
+	err := e.PrimaryKey.Serialize(w)
575
+	if err != nil {
576
+		return err
577
+	}
578
+	for _, ident := range e.Identities {
579
+		err = ident.UserId.Serialize(w)
580
+		if err != nil {
581
+			return err
582
+		}
583
+		err = ident.SelfSignature.Serialize(w)
584
+		if err != nil {
585
+			return err
586
+		}
587
+		for _, sig := range ident.Signatures {
588
+			err = sig.Serialize(w)
589
+			if err != nil {
590
+				return err
591
+			}
592
+		}
593
+	}
594
+	for _, subkey := range e.Subkeys {
595
+		err = subkey.PublicKey.Serialize(w)
596
+		if err != nil {
597
+			return err
598
+		}
599
+		err = subkey.Sig.Serialize(w)
600
+		if err != nil {
601
+			return err
602
+		}
603
+	}
604
+	return nil
605
+}
606
+
607
+// SignIdentity adds a signature to e, from signer, attesting that identity is
608
+// associated with e. The provided identity must already be an element of
609
+// e.Identities and the private key of signer must have been decrypted if
610
+// necessary.
611
+// If config is nil, sensible defaults will be used.
612
+func (e *Entity) SignIdentity(identity string, signer *Entity, config *packet.Config) error {
613
+	if signer.PrivateKey == nil {
614
+		return errors.InvalidArgumentError("signing Entity must have a private key")
615
+	}
616
+	if signer.PrivateKey.Encrypted {
617
+		return errors.InvalidArgumentError("signing Entity's private key must be decrypted")
618
+	}
619
+	ident, ok := e.Identities[identity]
620
+	if !ok {
621
+		return errors.InvalidArgumentError("given identity string not found in Entity")
622
+	}
623
+
624
+	sig := &packet.Signature{
625
+		SigType:      packet.SigTypeGenericCert,
626
+		PubKeyAlgo:   signer.PrivateKey.PubKeyAlgo,
627
+		Hash:         config.Hash(),
628
+		CreationTime: config.Now(),
629
+		IssuerKeyId:  &signer.PrivateKey.KeyId,
630
+	}
631
+	if err := sig.SignUserId(identity, e.PrimaryKey, signer.PrivateKey, config); err != nil {
632
+		return err
633
+	}
634
+	ident.Signatures = append(ident.Signatures, sig)
635
+	return nil
636
+}

+ 419
- 0
vendor/src/golang.org/x/crypto/openpgp/keys_test.go
文件差异内容过多而无法显示
查看文件


+ 123
- 0
vendor/src/golang.org/x/crypto/openpgp/packet/compressed.go 查看文件

@@ -0,0 +1,123 @@
1
+// Copyright 2011 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
+
5
+package packet
6
+
7
+import (
8
+	"compress/bzip2"
9
+	"compress/flate"
10
+	"compress/zlib"
11
+	"golang.org/x/crypto/openpgp/errors"
12
+	"io"
13
+	"strconv"
14
+)
15
+
16
+// Compressed represents a compressed OpenPGP packet. The decompressed contents
17
+// will contain more OpenPGP packets. See RFC 4880, section 5.6.
18
+type Compressed struct {
19
+	Body io.Reader
20
+}
21
+
22
+const (
23
+	NoCompression      = flate.NoCompression
24
+	BestSpeed          = flate.BestSpeed
25
+	BestCompression    = flate.BestCompression
26
+	DefaultCompression = flate.DefaultCompression
27
+)
28
+
29
+// CompressionConfig contains compressor configuration settings.
30
+type CompressionConfig struct {
31
+	// Level is the compression level to use. It must be set to
32
+	// between -1 and 9, with -1 causing the compressor to use the
33
+	// default compression level, 0 causing the compressor to use
34
+	// no compression and 1 to 9 representing increasing (better,
35
+	// slower) compression levels. If Level is less than -1 or
36
+	// more then 9, a non-nil error will be returned during
37
+	// encryption. See the constants above for convenient common
38
+	// settings for Level.
39
+	Level int
40
+}
41
+
42
+func (c *Compressed) parse(r io.Reader) error {
43
+	var buf [1]byte
44
+	_, err := readFull(r, buf[:])
45
+	if err != nil {
46
+		return err
47
+	}
48
+
49
+	switch buf[0] {
50
+	case 1:
51
+		c.Body = flate.NewReader(r)
52
+	case 2:
53
+		c.Body, err = zlib.NewReader(r)
54
+	case 3:
55
+		c.Body = bzip2.NewReader(r)
56
+	default:
57
+		err = errors.UnsupportedError("unknown compression algorithm: " + strconv.Itoa(int(buf[0])))
58
+	}
59
+
60
+	return err
61
+}
62
+
63
+// compressedWriterCloser represents the serialized compression stream
64
+// header and the compressor. Its Close() method ensures that both the
65
+// compressor and serialized stream header are closed. Its Write()
66
+// method writes to the compressor.
67
+type compressedWriteCloser struct {
68
+	sh io.Closer      // Stream Header
69
+	c  io.WriteCloser // Compressor
70
+}
71
+
72
+func (cwc compressedWriteCloser) Write(p []byte) (int, error) {
73
+	return cwc.c.Write(p)
74
+}
75
+
76
+func (cwc compressedWriteCloser) Close() (err error) {
77
+	err = cwc.c.Close()
78
+	if err != nil {
79
+		return err
80
+	}
81
+
82
+	return cwc.sh.Close()
83
+}
84
+
85
+// SerializeCompressed serializes a compressed data packet to w and
86
+// returns a WriteCloser to which the literal data packets themselves
87
+// can be written and which MUST be closed on completion. If cc is
88
+// nil, sensible defaults will be used to configure the compression
89
+// algorithm.
90
+func SerializeCompressed(w io.WriteCloser, algo CompressionAlgo, cc *CompressionConfig) (literaldata io.WriteCloser, err error) {
91
+	compressed, err := serializeStreamHeader(w, packetTypeCompressed)
92
+	if err != nil {
93
+		return
94
+	}
95
+
96
+	_, err = compressed.Write([]byte{uint8(algo)})
97
+	if err != nil {
98
+		return
99
+	}
100
+
101
+	level := DefaultCompression
102
+	if cc != nil {
103
+		level = cc.Level
104
+	}
105
+
106
+	var compressor io.WriteCloser
107
+	switch algo {
108
+	case CompressionZIP:
109
+		compressor, err = flate.NewWriter(compressed, level)
110
+	case CompressionZLIB:
111
+		compressor, err = zlib.NewWriterLevel(compressed, level)
112
+	default:
113
+		s := strconv.Itoa(int(algo))
114
+		err = errors.UnsupportedError("Unsupported compression algorithm: " + s)
115
+	}
116
+	if err != nil {
117
+		return
118
+	}
119
+
120
+	literaldata = compressedWriteCloser{compressed, compressor}
121
+
122
+	return
123
+}

+ 41
- 0
vendor/src/golang.org/x/crypto/openpgp/packet/compressed_test.go 查看文件

@@ -0,0 +1,41 @@
1
+// Copyright 2011 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
+
5
+package packet
6
+
7
+import (
8
+	"bytes"
9
+	"encoding/hex"
10
+	"io"
11
+	"io/ioutil"
12
+	"testing"
13
+)
14
+
15
+func TestCompressed(t *testing.T) {
16
+	packet, err := Read(readerFromHex(compressedHex))
17
+	if err != nil {
18
+		t.Errorf("failed to read Compressed: %s", err)
19
+		return
20
+	}
21
+
22
+	c, ok := packet.(*Compressed)
23
+	if !ok {
24
+		t.Error("didn't find Compressed packet")
25
+		return
26
+	}
27
+
28
+	contents, err := ioutil.ReadAll(c.Body)
29
+	if err != nil && err != io.EOF {
30
+		t.Error(err)
31
+		return
32
+	}
33
+
34
+	expected, _ := hex.DecodeString(compressedExpectedHex)
35
+	if !bytes.Equal(expected, contents) {
36
+		t.Errorf("got:%x want:%x", contents, expected)
37
+	}
38
+}
39
+
40
+const compressedHex = "a3013b2d90c4e02b72e25f727e5e496a5e49b11e1700"
41
+const compressedExpectedHex = "cb1062004d14c8fe636f6e74656e74732e0a"

+ 91
- 0
vendor/src/golang.org/x/crypto/openpgp/packet/config.go 查看文件

@@ -0,0 +1,91 @@
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
+
5
+package packet
6
+
7
+import (
8
+	"crypto"
9
+	"crypto/rand"
10
+	"io"
11
+	"time"
12
+)
13
+
14
+// Config collects a number of parameters along with sensible defaults.
15
+// A nil *Config is valid and results in all default values.
16
+type Config struct {
17
+	// Rand provides the source of entropy.
18
+	// If nil, the crypto/rand Reader is used.
19
+	Rand io.Reader
20
+	// DefaultHash is the default hash function to be used.
21
+	// If zero, SHA-256 is used.
22
+	DefaultHash crypto.Hash
23
+	// DefaultCipher is the cipher to be used.
24
+	// If zero, AES-128 is used.
25
+	DefaultCipher CipherFunction
26
+	// Time returns the current time as the number of seconds since the
27
+	// epoch. If Time is nil, time.Now is used.
28
+	Time func() time.Time
29
+	// DefaultCompressionAlgo is the compression algorithm to be
30
+	// applied to the plaintext before encryption. If zero, no
31
+	// compression is done.
32
+	DefaultCompressionAlgo CompressionAlgo
33
+	// CompressionConfig configures the compression settings.
34
+	CompressionConfig *CompressionConfig
35
+	// S2KCount is only used for symmetric encryption. It
36
+	// determines the strength of the passphrase stretching when
37
+	// the said passphrase is hashed to produce a key. S2KCount
38
+	// should be between 1024 and 65011712, inclusive. If Config
39
+	// is nil or S2KCount is 0, the value 65536 used. Not all
40
+	// values in the above range can be represented. S2KCount will
41
+	// be rounded up to the next representable value if it cannot
42
+	// be encoded exactly. When set, it is strongly encrouraged to
43
+	// use a value that is at least 65536. See RFC 4880 Section
44
+	// 3.7.1.3.
45
+	S2KCount int
46
+	// RSABits is the number of bits in new RSA keys made with NewEntity.
47
+	// If zero, then 2048 bit keys are created.
48
+	RSABits int
49
+}
50
+
51
+func (c *Config) Random() io.Reader {
52
+	if c == nil || c.Rand == nil {
53
+		return rand.Reader
54
+	}
55
+	return c.Rand
56
+}
57
+
58
+func (c *Config) Hash() crypto.Hash {
59
+	if c == nil || uint(c.DefaultHash) == 0 {
60
+		return crypto.SHA256
61
+	}
62
+	return c.DefaultHash
63
+}
64
+
65
+func (c *Config) Cipher() CipherFunction {
66
+	if c == nil || uint8(c.DefaultCipher) == 0 {
67
+		return CipherAES128
68
+	}
69
+	return c.DefaultCipher
70
+}
71
+
72
+func (c *Config) Now() time.Time {
73
+	if c == nil || c.Time == nil {
74
+		return time.Now()
75
+	}
76
+	return c.Time()
77
+}
78
+
79
+func (c *Config) Compression() CompressionAlgo {
80
+	if c == nil {
81
+		return CompressionNone
82
+	}
83
+	return c.DefaultCompressionAlgo
84
+}
85
+
86
+func (c *Config) PasswordHashIterations() int {
87
+	if c == nil || c.S2KCount == 0 {
88
+		return 0
89
+	}
90
+	return c.S2KCount
91
+}

+ 199
- 0
vendor/src/golang.org/x/crypto/openpgp/packet/encrypted_key.go 查看文件

@@ -0,0 +1,199 @@
1
+// Copyright 2011 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
+
5
+package packet
6
+
7
+import (
8
+	"crypto/rsa"
9
+	"encoding/binary"
10
+	"io"
11
+	"math/big"
12
+	"strconv"
13
+
14
+	"golang.org/x/crypto/openpgp/elgamal"
15
+	"golang.org/x/crypto/openpgp/errors"
16
+)
17
+
18
+const encryptedKeyVersion = 3
19
+
20
+// EncryptedKey represents a public-key encrypted session key. See RFC 4880,
21
+// section 5.1.
22
+type EncryptedKey struct {
23
+	KeyId      uint64
24
+	Algo       PublicKeyAlgorithm
25
+	CipherFunc CipherFunction // only valid after a successful Decrypt
26
+	Key        []byte         // only valid after a successful Decrypt
27
+
28
+	encryptedMPI1, encryptedMPI2 parsedMPI
29
+}
30
+
31
+func (e *EncryptedKey) parse(r io.Reader) (err error) {
32
+	var buf [10]byte
33
+	_, err = readFull(r, buf[:])
34
+	if err != nil {
35
+		return
36
+	}
37
+	if buf[0] != encryptedKeyVersion {
38
+		return errors.UnsupportedError("unknown EncryptedKey version " + strconv.Itoa(int(buf[0])))
39
+	}
40
+	e.KeyId = binary.BigEndian.Uint64(buf[1:9])
41
+	e.Algo = PublicKeyAlgorithm(buf[9])
42
+	switch e.Algo {
43
+	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly:
44
+		e.encryptedMPI1.bytes, e.encryptedMPI1.bitLength, err = readMPI(r)
45
+	case PubKeyAlgoElGamal:
46
+		e.encryptedMPI1.bytes, e.encryptedMPI1.bitLength, err = readMPI(r)
47
+		if err != nil {
48
+			return
49
+		}
50
+		e.encryptedMPI2.bytes, e.encryptedMPI2.bitLength, err = readMPI(r)
51
+	}
52
+	_, err = consumeAll(r)
53
+	return
54
+}
55
+
56
+func checksumKeyMaterial(key []byte) uint16 {
57
+	var checksum uint16
58
+	for _, v := range key {
59
+		checksum += uint16(v)
60
+	}
61
+	return checksum
62
+}
63
+
64
+// Decrypt decrypts an encrypted session key with the given private key. The
65
+// private key must have been decrypted first.
66
+// If config is nil, sensible defaults will be used.
67
+func (e *EncryptedKey) Decrypt(priv *PrivateKey, config *Config) error {
68
+	var err error
69
+	var b []byte
70
+
71
+	// TODO(agl): use session key decryption routines here to avoid
72
+	// padding oracle attacks.
73
+	switch priv.PubKeyAlgo {
74
+	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly:
75
+		b, err = rsa.DecryptPKCS1v15(config.Random(), priv.PrivateKey.(*rsa.PrivateKey), e.encryptedMPI1.bytes)
76
+	case PubKeyAlgoElGamal:
77
+		c1 := new(big.Int).SetBytes(e.encryptedMPI1.bytes)
78
+		c2 := new(big.Int).SetBytes(e.encryptedMPI2.bytes)
79
+		b, err = elgamal.Decrypt(priv.PrivateKey.(*elgamal.PrivateKey), c1, c2)
80
+	default:
81
+		err = errors.InvalidArgumentError("cannot decrypted encrypted session key with private key of type " + strconv.Itoa(int(priv.PubKeyAlgo)))
82
+	}
83
+
84
+	if err != nil {
85
+		return err
86
+	}
87
+
88
+	e.CipherFunc = CipherFunction(b[0])
89
+	e.Key = b[1 : len(b)-2]
90
+	expectedChecksum := uint16(b[len(b)-2])<<8 | uint16(b[len(b)-1])
91
+	checksum := checksumKeyMaterial(e.Key)
92
+	if checksum != expectedChecksum {
93
+		return errors.StructuralError("EncryptedKey checksum incorrect")
94
+	}
95
+
96
+	return nil
97
+}
98
+
99
+// Serialize writes the encrypted key packet, e, to w.
100
+func (e *EncryptedKey) Serialize(w io.Writer) error {
101
+	var mpiLen int
102
+	switch e.Algo {
103
+	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly:
104
+		mpiLen = 2 + len(e.encryptedMPI1.bytes)
105
+	case PubKeyAlgoElGamal:
106
+		mpiLen = 2 + len(e.encryptedMPI1.bytes) + 2 + len(e.encryptedMPI2.bytes)
107
+	default:
108
+		return errors.InvalidArgumentError("don't know how to serialize encrypted key type " + strconv.Itoa(int(e.Algo)))
109
+	}
110
+
111
+	serializeHeader(w, packetTypeEncryptedKey, 1 /* version */ +8 /* key id */ +1 /* algo */ +mpiLen)
112
+
113
+	w.Write([]byte{encryptedKeyVersion})
114
+	binary.Write(w, binary.BigEndian, e.KeyId)
115
+	w.Write([]byte{byte(e.Algo)})
116
+
117
+	switch e.Algo {
118
+	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly:
119
+		writeMPIs(w, e.encryptedMPI1)
120
+	case PubKeyAlgoElGamal:
121
+		writeMPIs(w, e.encryptedMPI1, e.encryptedMPI2)
122
+	default:
123
+		panic("internal error")
124
+	}
125
+
126
+	return nil
127
+}
128
+
129
+// SerializeEncryptedKey serializes an encrypted key packet to w that contains
130
+// key, encrypted to pub.
131
+// If config is nil, sensible defaults will be used.
132
+func SerializeEncryptedKey(w io.Writer, pub *PublicKey, cipherFunc CipherFunction, key []byte, config *Config) error {
133
+	var buf [10]byte
134
+	buf[0] = encryptedKeyVersion
135
+	binary.BigEndian.PutUint64(buf[1:9], pub.KeyId)
136
+	buf[9] = byte(pub.PubKeyAlgo)
137
+
138
+	keyBlock := make([]byte, 1 /* cipher type */ +len(key)+2 /* checksum */)
139
+	keyBlock[0] = byte(cipherFunc)
140
+	copy(keyBlock[1:], key)
141
+	checksum := checksumKeyMaterial(key)
142
+	keyBlock[1+len(key)] = byte(checksum >> 8)
143
+	keyBlock[1+len(key)+1] = byte(checksum)
144
+
145
+	switch pub.PubKeyAlgo {
146
+	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly:
147
+		return serializeEncryptedKeyRSA(w, config.Random(), buf, pub.PublicKey.(*rsa.PublicKey), keyBlock)
148
+	case PubKeyAlgoElGamal:
149
+		return serializeEncryptedKeyElGamal(w, config.Random(), buf, pub.PublicKey.(*elgamal.PublicKey), keyBlock)
150
+	case PubKeyAlgoDSA, PubKeyAlgoRSASignOnly:
151
+		return errors.InvalidArgumentError("cannot encrypt to public key of type " + strconv.Itoa(int(pub.PubKeyAlgo)))
152
+	}
153
+
154
+	return errors.UnsupportedError("encrypting a key to public key of type " + strconv.Itoa(int(pub.PubKeyAlgo)))
155
+}
156
+
157
+func serializeEncryptedKeyRSA(w io.Writer, rand io.Reader, header [10]byte, pub *rsa.PublicKey, keyBlock []byte) error {
158
+	cipherText, err := rsa.EncryptPKCS1v15(rand, pub, keyBlock)
159
+	if err != nil {
160
+		return errors.InvalidArgumentError("RSA encryption failed: " + err.Error())
161
+	}
162
+
163
+	packetLen := 10 /* header length */ + 2 /* mpi size */ + len(cipherText)
164
+
165
+	err = serializeHeader(w, packetTypeEncryptedKey, packetLen)
166
+	if err != nil {
167
+		return err
168
+	}
169
+	_, err = w.Write(header[:])
170
+	if err != nil {
171
+		return err
172
+	}
173
+	return writeMPI(w, 8*uint16(len(cipherText)), cipherText)
174
+}
175
+
176
+func serializeEncryptedKeyElGamal(w io.Writer, rand io.Reader, header [10]byte, pub *elgamal.PublicKey, keyBlock []byte) error {
177
+	c1, c2, err := elgamal.Encrypt(rand, pub, keyBlock)
178
+	if err != nil {
179
+		return errors.InvalidArgumentError("ElGamal encryption failed: " + err.Error())
180
+	}
181
+
182
+	packetLen := 10 /* header length */
183
+	packetLen += 2 /* mpi size */ + (c1.BitLen()+7)/8
184
+	packetLen += 2 /* mpi size */ + (c2.BitLen()+7)/8
185
+
186
+	err = serializeHeader(w, packetTypeEncryptedKey, packetLen)
187
+	if err != nil {
188
+		return err
189
+	}
190
+	_, err = w.Write(header[:])
191
+	if err != nil {
192
+		return err
193
+	}
194
+	err = writeBig(w, c1)
195
+	if err != nil {
196
+		return err
197
+	}
198
+	return writeBig(w, c2)
199
+}

+ 146
- 0
vendor/src/golang.org/x/crypto/openpgp/packet/encrypted_key_test.go 查看文件

@@ -0,0 +1,146 @@
1
+// Copyright 2011 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
+
5
+package packet
6
+
7
+import (
8
+	"bytes"
9
+	"crypto/rsa"
10
+	"encoding/hex"
11
+	"fmt"
12
+	"math/big"
13
+	"testing"
14
+)
15
+
16
+func bigFromBase10(s string) *big.Int {
17
+	b, ok := new(big.Int).SetString(s, 10)
18
+	if !ok {
19
+		panic("bigFromBase10 failed")
20
+	}
21
+	return b
22
+}
23
+
24
+var encryptedKeyPub = rsa.PublicKey{
25
+	E: 65537,
26
+	N: bigFromBase10("115804063926007623305902631768113868327816898845124614648849934718568541074358183759250136204762053879858102352159854352727097033322663029387610959884180306668628526686121021235757016368038585212410610742029286439607686208110250133174279811431933746643015923132833417396844716207301518956640020862630546868823"),
27
+}
28
+
29
+var encryptedKeyRSAPriv = &rsa.PrivateKey{
30
+	PublicKey: encryptedKeyPub,
31
+	D:         bigFromBase10("32355588668219869544751561565313228297765464314098552250409557267371233892496951383426602439009993875125222579159850054973310859166139474359774543943714622292329487391199285040721944491839695981199720170366763547754915493640685849961780092241140181198779299712578774460837139360803883139311171713302987058393"),
32
+}
33
+
34
+var encryptedKeyPriv = &PrivateKey{
35
+	PublicKey: PublicKey{
36
+		PubKeyAlgo: PubKeyAlgoRSA,
37
+	},
38
+	PrivateKey: encryptedKeyRSAPriv,
39
+}
40
+
41
+func TestDecryptingEncryptedKey(t *testing.T) {
42
+	const encryptedKeyHex = "c18c032a67d68660df41c70104005789d0de26b6a50c985a02a13131ca829c413a35d0e6fa8d6842599252162808ac7439c72151c8c6183e76923fe3299301414d0c25a2f06a2257db3839e7df0ec964773f6e4c4ac7ff3b48c444237166dd46ba8ff443a5410dc670cb486672fdbe7c9dfafb75b4fea83af3a204fe2a7dfa86bd20122b4f3d2646cbeecb8f7be8"
43
+	const expectedKeyHex = "d930363f7e0308c333b9618617ea728963d8df993665ae7be1092d4926fd864b"
44
+
45
+	p, err := Read(readerFromHex(encryptedKeyHex))
46
+	if err != nil {
47
+		t.Errorf("error from Read: %s", err)
48
+		return
49
+	}
50
+	ek, ok := p.(*EncryptedKey)
51
+	if !ok {
52
+		t.Errorf("didn't parse an EncryptedKey, got %#v", p)
53
+		return
54
+	}
55
+
56
+	if ek.KeyId != 0x2a67d68660df41c7 || ek.Algo != PubKeyAlgoRSA {
57
+		t.Errorf("unexpected EncryptedKey contents: %#v", ek)
58
+		return
59
+	}
60
+
61
+	err = ek.Decrypt(encryptedKeyPriv, nil)
62
+	if err != nil {
63
+		t.Errorf("error from Decrypt: %s", err)
64
+		return
65
+	}
66
+
67
+	if ek.CipherFunc != CipherAES256 {
68
+		t.Errorf("unexpected EncryptedKey contents: %#v", ek)
69
+		return
70
+	}
71
+
72
+	keyHex := fmt.Sprintf("%x", ek.Key)
73
+	if keyHex != expectedKeyHex {
74
+		t.Errorf("bad key, got %s want %x", keyHex, expectedKeyHex)
75
+	}
76
+}
77
+
78
+func TestEncryptingEncryptedKey(t *testing.T) {
79
+	key := []byte{1, 2, 3, 4}
80
+	const expectedKeyHex = "01020304"
81
+	const keyId = 42
82
+
83
+	pub := &PublicKey{
84
+		PublicKey:  &encryptedKeyPub,
85
+		KeyId:      keyId,
86
+		PubKeyAlgo: PubKeyAlgoRSAEncryptOnly,
87
+	}
88
+
89
+	buf := new(bytes.Buffer)
90
+	err := SerializeEncryptedKey(buf, pub, CipherAES128, key, nil)
91
+	if err != nil {
92
+		t.Errorf("error writing encrypted key packet: %s", err)
93
+	}
94
+
95
+	p, err := Read(buf)
96
+	if err != nil {
97
+		t.Errorf("error from Read: %s", err)
98
+		return
99
+	}
100
+	ek, ok := p.(*EncryptedKey)
101
+	if !ok {
102
+		t.Errorf("didn't parse an EncryptedKey, got %#v", p)
103
+		return
104
+	}
105
+
106
+	if ek.KeyId != keyId || ek.Algo != PubKeyAlgoRSAEncryptOnly {
107
+		t.Errorf("unexpected EncryptedKey contents: %#v", ek)
108
+		return
109
+	}
110
+
111
+	err = ek.Decrypt(encryptedKeyPriv, nil)
112
+	if err != nil {
113
+		t.Errorf("error from Decrypt: %s", err)
114
+		return
115
+	}
116
+
117
+	if ek.CipherFunc != CipherAES128 {
118
+		t.Errorf("unexpected EncryptedKey contents: %#v", ek)
119
+		return
120
+	}
121
+
122
+	keyHex := fmt.Sprintf("%x", ek.Key)
123
+	if keyHex != expectedKeyHex {
124
+		t.Errorf("bad key, got %s want %x", keyHex, expectedKeyHex)
125
+	}
126
+}
127
+
128
+func TestSerializingEncryptedKey(t *testing.T) {
129
+	const encryptedKeyHex = "c18c032a67d68660df41c70104005789d0de26b6a50c985a02a13131ca829c413a35d0e6fa8d6842599252162808ac7439c72151c8c6183e76923fe3299301414d0c25a2f06a2257db3839e7df0ec964773f6e4c4ac7ff3b48c444237166dd46ba8ff443a5410dc670cb486672fdbe7c9dfafb75b4fea83af3a204fe2a7dfa86bd20122b4f3d2646cbeecb8f7be8"
130
+
131
+	p, err := Read(readerFromHex(encryptedKeyHex))
132
+	if err != nil {
133
+		t.Fatalf("error from Read: %s", err)
134
+	}
135
+	ek, ok := p.(*EncryptedKey)
136
+	if !ok {
137
+		t.Fatalf("didn't parse an EncryptedKey, got %#v", p)
138
+	}
139
+
140
+	var buf bytes.Buffer
141
+	ek.Serialize(&buf)
142
+
143
+	if bufHex := hex.EncodeToString(buf.Bytes()); bufHex != encryptedKeyHex {
144
+		t.Fatalf("serialization of encrypted key differed from original. Original was %s, but reserialized as %s", encryptedKeyHex, bufHex)
145
+	}
146
+}

+ 89
- 0
vendor/src/golang.org/x/crypto/openpgp/packet/literal.go 查看文件

@@ -0,0 +1,89 @@
1
+// Copyright 2011 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
+
5
+package packet
6
+
7
+import (
8
+	"encoding/binary"
9
+	"io"
10
+)
11
+
12
+// LiteralData represents an encrypted file. See RFC 4880, section 5.9.
13
+type LiteralData struct {
14
+	IsBinary bool
15
+	FileName string
16
+	Time     uint32 // Unix epoch time. Either creation time or modification time. 0 means undefined.
17
+	Body     io.Reader
18
+}
19
+
20
+// ForEyesOnly returns whether the contents of the LiteralData have been marked
21
+// as especially sensitive.
22
+func (l *LiteralData) ForEyesOnly() bool {
23
+	return l.FileName == "_CONSOLE"
24
+}
25
+
26
+func (l *LiteralData) parse(r io.Reader) (err error) {
27
+	var buf [256]byte
28
+
29
+	_, err = readFull(r, buf[:2])
30
+	if err != nil {
31
+		return
32
+	}
33
+
34
+	l.IsBinary = buf[0] == 'b'
35
+	fileNameLen := int(buf[1])
36
+
37
+	_, err = readFull(r, buf[:fileNameLen])
38
+	if err != nil {
39
+		return
40
+	}
41
+
42
+	l.FileName = string(buf[:fileNameLen])
43
+
44
+	_, err = readFull(r, buf[:4])
45
+	if err != nil {
46
+		return
47
+	}
48
+
49
+	l.Time = binary.BigEndian.Uint32(buf[:4])
50
+	l.Body = r
51
+	return
52
+}
53
+
54
+// SerializeLiteral serializes a literal data packet to w and returns a
55
+// WriteCloser to which the data itself can be written and which MUST be closed
56
+// on completion. The fileName is truncated to 255 bytes.
57
+func SerializeLiteral(w io.WriteCloser, isBinary bool, fileName string, time uint32) (plaintext io.WriteCloser, err error) {
58
+	var buf [4]byte
59
+	buf[0] = 't'
60
+	if isBinary {
61
+		buf[0] = 'b'
62
+	}
63
+	if len(fileName) > 255 {
64
+		fileName = fileName[:255]
65
+	}
66
+	buf[1] = byte(len(fileName))
67
+
68
+	inner, err := serializeStreamHeader(w, packetTypeLiteralData)
69
+	if err != nil {
70
+		return
71
+	}
72
+
73
+	_, err = inner.Write(buf[:2])
74
+	if err != nil {
75
+		return
76
+	}
77
+	_, err = inner.Write([]byte(fileName))
78
+	if err != nil {
79
+		return
80
+	}
81
+	binary.BigEndian.PutUint32(buf[:], time)
82
+	_, err = inner.Write(buf[:])
83
+	if err != nil {
84
+		return
85
+	}
86
+
87
+	plaintext = inner
88
+	return
89
+}

+ 143
- 0
vendor/src/golang.org/x/crypto/openpgp/packet/ocfb.go 查看文件

@@ -0,0 +1,143 @@
1
+// Copyright 2010 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
+
5
+// OpenPGP CFB Mode. http://tools.ietf.org/html/rfc4880#section-13.9
6
+
7
+package packet
8
+
9
+import (
10
+	"crypto/cipher"
11
+)
12
+
13
+type ocfbEncrypter struct {
14
+	b       cipher.Block
15
+	fre     []byte
16
+	outUsed int
17
+}
18
+
19
+// An OCFBResyncOption determines if the "resynchronization step" of OCFB is
20
+// performed.
21
+type OCFBResyncOption bool
22
+
23
+const (
24
+	OCFBResync   OCFBResyncOption = true
25
+	OCFBNoResync OCFBResyncOption = false
26
+)
27
+
28
+// NewOCFBEncrypter returns a cipher.Stream which encrypts data with OpenPGP's
29
+// cipher feedback mode using the given cipher.Block, and an initial amount of
30
+// ciphertext.  randData must be random bytes and be the same length as the
31
+// cipher.Block's block size. Resync determines if the "resynchronization step"
32
+// from RFC 4880, 13.9 step 7 is performed. Different parts of OpenPGP vary on
33
+// this point.
34
+func NewOCFBEncrypter(block cipher.Block, randData []byte, resync OCFBResyncOption) (cipher.Stream, []byte) {
35
+	blockSize := block.BlockSize()
36
+	if len(randData) != blockSize {
37
+		return nil, nil
38
+	}
39
+
40
+	x := &ocfbEncrypter{
41
+		b:       block,
42
+		fre:     make([]byte, blockSize),
43
+		outUsed: 0,
44
+	}
45
+	prefix := make([]byte, blockSize+2)
46
+
47
+	block.Encrypt(x.fre, x.fre)
48
+	for i := 0; i < blockSize; i++ {
49
+		prefix[i] = randData[i] ^ x.fre[i]
50
+	}
51
+
52
+	block.Encrypt(x.fre, prefix[:blockSize])
53
+	prefix[blockSize] = x.fre[0] ^ randData[blockSize-2]
54
+	prefix[blockSize+1] = x.fre[1] ^ randData[blockSize-1]
55
+
56
+	if resync {
57
+		block.Encrypt(x.fre, prefix[2:])
58
+	} else {
59
+		x.fre[0] = prefix[blockSize]
60
+		x.fre[1] = prefix[blockSize+1]
61
+		x.outUsed = 2
62
+	}
63
+	return x, prefix
64
+}
65
+
66
+func (x *ocfbEncrypter) XORKeyStream(dst, src []byte) {
67
+	for i := 0; i < len(src); i++ {
68
+		if x.outUsed == len(x.fre) {
69
+			x.b.Encrypt(x.fre, x.fre)
70
+			x.outUsed = 0
71
+		}
72
+
73
+		x.fre[x.outUsed] ^= src[i]
74
+		dst[i] = x.fre[x.outUsed]
75
+		x.outUsed++
76
+	}
77
+}
78
+
79
+type ocfbDecrypter struct {
80
+	b       cipher.Block
81
+	fre     []byte
82
+	outUsed int
83
+}
84
+
85
+// NewOCFBDecrypter returns a cipher.Stream which decrypts data with OpenPGP's
86
+// cipher feedback mode using the given cipher.Block. Prefix must be the first
87
+// blockSize + 2 bytes of the ciphertext, where blockSize is the cipher.Block's
88
+// block size. If an incorrect key is detected then nil is returned. On
89
+// successful exit, blockSize+2 bytes of decrypted data are written into
90
+// prefix. Resync determines if the "resynchronization step" from RFC 4880,
91
+// 13.9 step 7 is performed. Different parts of OpenPGP vary on this point.
92
+func NewOCFBDecrypter(block cipher.Block, prefix []byte, resync OCFBResyncOption) cipher.Stream {
93
+	blockSize := block.BlockSize()
94
+	if len(prefix) != blockSize+2 {
95
+		return nil
96
+	}
97
+
98
+	x := &ocfbDecrypter{
99
+		b:       block,
100
+		fre:     make([]byte, blockSize),
101
+		outUsed: 0,
102
+	}
103
+	prefixCopy := make([]byte, len(prefix))
104
+	copy(prefixCopy, prefix)
105
+
106
+	block.Encrypt(x.fre, x.fre)
107
+	for i := 0; i < blockSize; i++ {
108
+		prefixCopy[i] ^= x.fre[i]
109
+	}
110
+
111
+	block.Encrypt(x.fre, prefix[:blockSize])
112
+	prefixCopy[blockSize] ^= x.fre[0]
113
+	prefixCopy[blockSize+1] ^= x.fre[1]
114
+
115
+	if prefixCopy[blockSize-2] != prefixCopy[blockSize] ||
116
+		prefixCopy[blockSize-1] != prefixCopy[blockSize+1] {
117
+		return nil
118
+	}
119
+
120
+	if resync {
121
+		block.Encrypt(x.fre, prefix[2:])
122
+	} else {
123
+		x.fre[0] = prefix[blockSize]
124
+		x.fre[1] = prefix[blockSize+1]
125
+		x.outUsed = 2
126
+	}
127
+	copy(prefix, prefixCopy)
128
+	return x
129
+}
130
+
131
+func (x *ocfbDecrypter) XORKeyStream(dst, src []byte) {
132
+	for i := 0; i < len(src); i++ {
133
+		if x.outUsed == len(x.fre) {
134
+			x.b.Encrypt(x.fre, x.fre)
135
+			x.outUsed = 0
136
+		}
137
+
138
+		c := src[i]
139
+		dst[i] = x.fre[x.outUsed] ^ src[i]
140
+		x.fre[x.outUsed] = c
141
+		x.outUsed++
142
+	}
143
+}

+ 46
- 0
vendor/src/golang.org/x/crypto/openpgp/packet/ocfb_test.go 查看文件

@@ -0,0 +1,46 @@
1
+// Copyright 2010 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
+
5
+package packet
6
+
7
+import (
8
+	"bytes"
9
+	"crypto/aes"
10
+	"crypto/rand"
11
+	"testing"
12
+)
13
+
14
+var commonKey128 = []byte{0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}
15
+
16
+func testOCFB(t *testing.T, resync OCFBResyncOption) {
17
+	block, err := aes.NewCipher(commonKey128)
18
+	if err != nil {
19
+		t.Error(err)
20
+		return
21
+	}
22
+
23
+	plaintext := []byte("this is the plaintext, which is long enough to span several blocks.")
24
+	randData := make([]byte, block.BlockSize())
25
+	rand.Reader.Read(randData)
26
+	ocfb, prefix := NewOCFBEncrypter(block, randData, resync)
27
+	ciphertext := make([]byte, len(plaintext))
28
+	ocfb.XORKeyStream(ciphertext, plaintext)
29
+
30
+	ocfbdec := NewOCFBDecrypter(block, prefix, resync)
31
+	if ocfbdec == nil {
32
+		t.Errorf("NewOCFBDecrypter failed (resync: %t)", resync)
33
+		return
34
+	}
35
+	plaintextCopy := make([]byte, len(plaintext))
36
+	ocfbdec.XORKeyStream(plaintextCopy, ciphertext)
37
+
38
+	if !bytes.Equal(plaintextCopy, plaintext) {
39
+		t.Errorf("got: %x, want: %x (resync: %t)", plaintextCopy, plaintext, resync)
40
+	}
41
+}
42
+
43
+func TestOCFB(t *testing.T) {
44
+	testOCFB(t, OCFBNoResync)
45
+	testOCFB(t, OCFBResync)
46
+}

+ 73
- 0
vendor/src/golang.org/x/crypto/openpgp/packet/one_pass_signature.go 查看文件

@@ -0,0 +1,73 @@
1
+// Copyright 2011 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
+
5
+package packet
6
+
7
+import (
8
+	"crypto"
9
+	"encoding/binary"
10
+	"golang.org/x/crypto/openpgp/errors"
11
+	"golang.org/x/crypto/openpgp/s2k"
12
+	"io"
13
+	"strconv"
14
+)
15
+
16
+// OnePassSignature represents a one-pass signature packet. See RFC 4880,
17
+// section 5.4.
18
+type OnePassSignature struct {
19
+	SigType    SignatureType
20
+	Hash       crypto.Hash
21
+	PubKeyAlgo PublicKeyAlgorithm
22
+	KeyId      uint64
23
+	IsLast     bool
24
+}
25
+
26
+const onePassSignatureVersion = 3
27
+
28
+func (ops *OnePassSignature) parse(r io.Reader) (err error) {
29
+	var buf [13]byte
30
+
31
+	_, err = readFull(r, buf[:])
32
+	if err != nil {
33
+		return
34
+	}
35
+	if buf[0] != onePassSignatureVersion {
36
+		err = errors.UnsupportedError("one-pass-signature packet version " + strconv.Itoa(int(buf[0])))
37
+	}
38
+
39
+	var ok bool
40
+	ops.Hash, ok = s2k.HashIdToHash(buf[2])
41
+	if !ok {
42
+		return errors.UnsupportedError("hash function: " + strconv.Itoa(int(buf[2])))
43
+	}
44
+
45
+	ops.SigType = SignatureType(buf[1])
46
+	ops.PubKeyAlgo = PublicKeyAlgorithm(buf[3])
47
+	ops.KeyId = binary.BigEndian.Uint64(buf[4:12])
48
+	ops.IsLast = buf[12] != 0
49
+	return
50
+}
51
+
52
+// Serialize marshals the given OnePassSignature to w.
53
+func (ops *OnePassSignature) Serialize(w io.Writer) error {
54
+	var buf [13]byte
55
+	buf[0] = onePassSignatureVersion
56
+	buf[1] = uint8(ops.SigType)
57
+	var ok bool
58
+	buf[2], ok = s2k.HashToHashId(ops.Hash)
59
+	if !ok {
60
+		return errors.UnsupportedError("hash type: " + strconv.Itoa(int(ops.Hash)))
61
+	}
62
+	buf[3] = uint8(ops.PubKeyAlgo)
63
+	binary.BigEndian.PutUint64(buf[4:12], ops.KeyId)
64
+	if ops.IsLast {
65
+		buf[12] = 1
66
+	}
67
+
68
+	if err := serializeHeader(w, packetTypeOnePassSignature, len(buf)); err != nil {
69
+		return err
70
+	}
71
+	_, err := w.Write(buf[:])
72
+	return err
73
+}

+ 162
- 0
vendor/src/golang.org/x/crypto/openpgp/packet/opaque.go 查看文件

@@ -0,0 +1,162 @@
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
+
5
+package packet
6
+
7
+import (
8
+	"bytes"
9
+	"io"
10
+	"io/ioutil"
11
+
12
+	"golang.org/x/crypto/openpgp/errors"
13
+)
14
+
15
+// OpaquePacket represents an OpenPGP packet as raw, unparsed data. This is
16
+// useful for splitting and storing the original packet contents separately,
17
+// handling unsupported packet types or accessing parts of the packet not yet
18
+// implemented by this package.
19
+type OpaquePacket struct {
20
+	// Packet type
21
+	Tag uint8
22
+	// Reason why the packet was parsed opaquely
23
+	Reason error
24
+	// Binary contents of the packet data
25
+	Contents []byte
26
+}
27
+
28
+func (op *OpaquePacket) parse(r io.Reader) (err error) {
29
+	op.Contents, err = ioutil.ReadAll(r)
30
+	return
31
+}
32
+
33
+// Serialize marshals the packet to a writer in its original form, including
34
+// the packet header.
35
+func (op *OpaquePacket) Serialize(w io.Writer) (err error) {
36
+	err = serializeHeader(w, packetType(op.Tag), len(op.Contents))
37
+	if err == nil {
38
+		_, err = w.Write(op.Contents)
39
+	}
40
+	return
41
+}
42
+
43
+// Parse attempts to parse the opaque contents into a structure supported by
44
+// this package. If the packet is not known then the result will be another
45
+// OpaquePacket.
46
+func (op *OpaquePacket) Parse() (p Packet, err error) {
47
+	hdr := bytes.NewBuffer(nil)
48
+	err = serializeHeader(hdr, packetType(op.Tag), len(op.Contents))
49
+	if err != nil {
50
+		op.Reason = err
51
+		return op, err
52
+	}
53
+	p, err = Read(io.MultiReader(hdr, bytes.NewBuffer(op.Contents)))
54
+	if err != nil {
55
+		op.Reason = err
56
+		p = op
57
+	}
58
+	return
59
+}
60
+
61
+// OpaqueReader reads OpaquePackets from an io.Reader.
62
+type OpaqueReader struct {
63
+	r io.Reader
64
+}
65
+
66
+func NewOpaqueReader(r io.Reader) *OpaqueReader {
67
+	return &OpaqueReader{r: r}
68
+}
69
+
70
+// Read the next OpaquePacket.
71
+func (or *OpaqueReader) Next() (op *OpaquePacket, err error) {
72
+	tag, _, contents, err := readHeader(or.r)
73
+	if err != nil {
74
+		return
75
+	}
76
+	op = &OpaquePacket{Tag: uint8(tag), Reason: err}
77
+	err = op.parse(contents)
78
+	if err != nil {
79
+		consumeAll(contents)
80
+	}
81
+	return
82
+}
83
+
84
+// OpaqueSubpacket represents an unparsed OpenPGP subpacket,
85
+// as found in signature and user attribute packets.
86
+type OpaqueSubpacket struct {
87
+	SubType  uint8
88
+	Contents []byte
89
+}
90
+
91
+// OpaqueSubpackets extracts opaque, unparsed OpenPGP subpackets from
92
+// their byte representation.
93
+func OpaqueSubpackets(contents []byte) (result []*OpaqueSubpacket, err error) {
94
+	var (
95
+		subHeaderLen int
96
+		subPacket    *OpaqueSubpacket
97
+	)
98
+	for len(contents) > 0 {
99
+		subHeaderLen, subPacket, err = nextSubpacket(contents)
100
+		if err != nil {
101
+			break
102
+		}
103
+		result = append(result, subPacket)
104
+		contents = contents[subHeaderLen+len(subPacket.Contents):]
105
+	}
106
+	return
107
+}
108
+
109
+func nextSubpacket(contents []byte) (subHeaderLen int, subPacket *OpaqueSubpacket, err error) {
110
+	// RFC 4880, section 5.2.3.1
111
+	var subLen uint32
112
+	if len(contents) < 1 {
113
+		goto Truncated
114
+	}
115
+	subPacket = &OpaqueSubpacket{}
116
+	switch {
117
+	case contents[0] < 192:
118
+		subHeaderLen = 2 // 1 length byte, 1 subtype byte
119
+		if len(contents) < subHeaderLen {
120
+			goto Truncated
121
+		}
122
+		subLen = uint32(contents[0])
123
+		contents = contents[1:]
124
+	case contents[0] < 255:
125
+		subHeaderLen = 3 // 2 length bytes, 1 subtype
126
+		if len(contents) < subHeaderLen {
127
+			goto Truncated
128
+		}
129
+		subLen = uint32(contents[0]-192)<<8 + uint32(contents[1]) + 192
130
+		contents = contents[2:]
131
+	default:
132
+		subHeaderLen = 6 // 5 length bytes, 1 subtype
133
+		if len(contents) < subHeaderLen {
134
+			goto Truncated
135
+		}
136
+		subLen = uint32(contents[1])<<24 |
137
+			uint32(contents[2])<<16 |
138
+			uint32(contents[3])<<8 |
139
+			uint32(contents[4])
140
+		contents = contents[5:]
141
+	}
142
+	if subLen > uint32(len(contents)) || subLen == 0 {
143
+		goto Truncated
144
+	}
145
+	subPacket.SubType = contents[0]
146
+	subPacket.Contents = contents[1:subLen]
147
+	return
148
+Truncated:
149
+	err = errors.StructuralError("subpacket truncated")
150
+	return
151
+}
152
+
153
+func (osp *OpaqueSubpacket) Serialize(w io.Writer) (err error) {
154
+	buf := make([]byte, 6)
155
+	n := serializeSubpacketLength(buf, len(osp.Contents)+1)
156
+	buf[n] = osp.SubType
157
+	if _, err = w.Write(buf[:n+1]); err != nil {
158
+		return
159
+	}
160
+	_, err = w.Write(osp.Contents)
161
+	return
162
+}

+ 67
- 0
vendor/src/golang.org/x/crypto/openpgp/packet/opaque_test.go 查看文件

@@ -0,0 +1,67 @@
1
+// Copyright 2011 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
+
5
+package packet
6
+
7
+import (
8
+	"bytes"
9
+	"encoding/hex"
10
+	"io"
11
+	"testing"
12
+)
13
+
14
+// Test packet.Read error handling in OpaquePacket.Parse,
15
+// which attempts to re-read an OpaquePacket as a supported
16
+// Packet type.
17
+func TestOpaqueParseReason(t *testing.T) {
18
+	buf, err := hex.DecodeString(UnsupportedKeyHex)
19
+	if err != nil {
20
+		t.Fatal(err)
21
+	}
22
+	or := NewOpaqueReader(bytes.NewBuffer(buf))
23
+	count := 0
24
+	badPackets := 0
25
+	var uid *UserId
26
+	for {
27
+		op, err := or.Next()
28
+		if err == io.EOF {
29
+			break
30
+		} else if err != nil {
31
+			t.Errorf("#%d: opaque read error: %v", count, err)
32
+			break
33
+		}
34
+		// try to parse opaque packet
35
+		p, err := op.Parse()
36
+		switch pkt := p.(type) {
37
+		case *UserId:
38
+			uid = pkt
39
+		case *OpaquePacket:
40
+			// If an OpaquePacket can't re-parse, packet.Read
41
+			// certainly had its reasons.
42
+			if pkt.Reason == nil {
43
+				t.Errorf("#%d: opaque packet, no reason", count)
44
+			} else {
45
+				badPackets++
46
+			}
47
+		}
48
+		count++
49
+	}
50
+
51
+	const expectedBad = 3
52
+	// Test post-conditions, make sure we actually parsed packets as expected.
53
+	if badPackets != expectedBad {
54
+		t.Errorf("unexpected # unparseable packets: %d (want %d)", badPackets, expectedBad)
55
+	}
56
+	if uid == nil {
57
+		t.Errorf("failed to find expected UID in unsupported keyring")
58
+	} else if uid.Id != "Armin M. Warda <warda@nephilim.ruhr.de>" {
59
+		t.Errorf("unexpected UID: %v", uid.Id)
60
+	}
61
+}
62
+
63
+// This key material has public key and signature packet versions modified to
64
+// an unsupported value (1), so that trying to parse the OpaquePacket to
65
+// a typed packet will get an error. It also contains a GnuPG trust packet.
66
+// (Created with: od -An -t x1 pubring.gpg | xargs | sed 's/ //g')
67
+const UnsupportedKeyHex = `988d012e7a18a20000010400d6ac00d92b89c1f4396c243abb9b76d2e9673ad63483291fed88e22b82e255e441c078c6abbbf7d2d195e50b62eeaa915b85b0ec20c225ce2c64c167cacb6e711daf2e45da4a8356a059b8160e3b3628ac0dd8437b31f06d53d6e8ea4214d4a26406a6b63e1001406ef23e0bb3069fac9a99a91f77dfafd5de0f188a5da5e3c9000511b42741726d696e204d2e205761726461203c7761726461406e657068696c696d2e727568722e64653e8900950105102e8936c705d1eb399e58489901013f0e03ff5a0c4f421e34fcfa388129166420c08cd76987bcdec6f01bd0271459a85cc22048820dd4e44ac2c7d23908d540f54facf1b36b0d9c20488781ce9dca856531e76e2e846826e9951338020a03a09b57aa5faa82e9267458bd76105399885ac35af7dc1cbb6aaed7c39e1039f3b5beda2c0e916bd38560509bab81235d1a0ead83b0020000`

+ 537
- 0
vendor/src/golang.org/x/crypto/openpgp/packet/packet.go 查看文件

@@ -0,0 +1,537 @@
1
+// Copyright 2011 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
+
5
+// Package packet implements parsing and serialization of OpenPGP packets, as
6
+// specified in RFC 4880.
7
+package packet // import "golang.org/x/crypto/openpgp/packet"
8
+
9
+import (
10
+	"bufio"
11
+	"crypto/aes"
12
+	"crypto/cipher"
13
+	"crypto/des"
14
+	"golang.org/x/crypto/cast5"
15
+	"golang.org/x/crypto/openpgp/errors"
16
+	"io"
17
+	"math/big"
18
+)
19
+
20
+// readFull is the same as io.ReadFull except that reading zero bytes returns
21
+// ErrUnexpectedEOF rather than EOF.
22
+func readFull(r io.Reader, buf []byte) (n int, err error) {
23
+	n, err = io.ReadFull(r, buf)
24
+	if err == io.EOF {
25
+		err = io.ErrUnexpectedEOF
26
+	}
27
+	return
28
+}
29
+
30
+// readLength reads an OpenPGP length from r. See RFC 4880, section 4.2.2.
31
+func readLength(r io.Reader) (length int64, isPartial bool, err error) {
32
+	var buf [4]byte
33
+	_, err = readFull(r, buf[:1])
34
+	if err != nil {
35
+		return
36
+	}
37
+	switch {
38
+	case buf[0] < 192:
39
+		length = int64(buf[0])
40
+	case buf[0] < 224:
41
+		length = int64(buf[0]-192) << 8
42
+		_, err = readFull(r, buf[0:1])
43
+		if err != nil {
44
+			return
45
+		}
46
+		length += int64(buf[0]) + 192
47
+	case buf[0] < 255:
48
+		length = int64(1) << (buf[0] & 0x1f)
49
+		isPartial = true
50
+	default:
51
+		_, err = readFull(r, buf[0:4])
52
+		if err != nil {
53
+			return
54
+		}
55
+		length = int64(buf[0])<<24 |
56
+			int64(buf[1])<<16 |
57
+			int64(buf[2])<<8 |
58
+			int64(buf[3])
59
+	}
60
+	return
61
+}
62
+
63
+// partialLengthReader wraps an io.Reader and handles OpenPGP partial lengths.
64
+// The continuation lengths are parsed and removed from the stream and EOF is
65
+// returned at the end of the packet. See RFC 4880, section 4.2.2.4.
66
+type partialLengthReader struct {
67
+	r         io.Reader
68
+	remaining int64
69
+	isPartial bool
70
+}
71
+
72
+func (r *partialLengthReader) Read(p []byte) (n int, err error) {
73
+	for r.remaining == 0 {
74
+		if !r.isPartial {
75
+			return 0, io.EOF
76
+		}
77
+		r.remaining, r.isPartial, err = readLength(r.r)
78
+		if err != nil {
79
+			return 0, err
80
+		}
81
+	}
82
+
83
+	toRead := int64(len(p))
84
+	if toRead > r.remaining {
85
+		toRead = r.remaining
86
+	}
87
+
88
+	n, err = r.r.Read(p[:int(toRead)])
89
+	r.remaining -= int64(n)
90
+	if n < int(toRead) && err == io.EOF {
91
+		err = io.ErrUnexpectedEOF
92
+	}
93
+	return
94
+}
95
+
96
+// partialLengthWriter writes a stream of data using OpenPGP partial lengths.
97
+// See RFC 4880, section 4.2.2.4.
98
+type partialLengthWriter struct {
99
+	w          io.WriteCloser
100
+	lengthByte [1]byte
101
+}
102
+
103
+func (w *partialLengthWriter) Write(p []byte) (n int, err error) {
104
+	for len(p) > 0 {
105
+		for power := uint(14); power < 32; power-- {
106
+			l := 1 << power
107
+			if len(p) >= l {
108
+				w.lengthByte[0] = 224 + uint8(power)
109
+				_, err = w.w.Write(w.lengthByte[:])
110
+				if err != nil {
111
+					return
112
+				}
113
+				var m int
114
+				m, err = w.w.Write(p[:l])
115
+				n += m
116
+				if err != nil {
117
+					return
118
+				}
119
+				p = p[l:]
120
+				break
121
+			}
122
+		}
123
+	}
124
+	return
125
+}
126
+
127
+func (w *partialLengthWriter) Close() error {
128
+	w.lengthByte[0] = 0
129
+	_, err := w.w.Write(w.lengthByte[:])
130
+	if err != nil {
131
+		return err
132
+	}
133
+	return w.w.Close()
134
+}
135
+
136
+// A spanReader is an io.LimitReader, but it returns ErrUnexpectedEOF if the
137
+// underlying Reader returns EOF before the limit has been reached.
138
+type spanReader struct {
139
+	r io.Reader
140
+	n int64
141
+}
142
+
143
+func (l *spanReader) Read(p []byte) (n int, err error) {
144
+	if l.n <= 0 {
145
+		return 0, io.EOF
146
+	}
147
+	if int64(len(p)) > l.n {
148
+		p = p[0:l.n]
149
+	}
150
+	n, err = l.r.Read(p)
151
+	l.n -= int64(n)
152
+	if l.n > 0 && err == io.EOF {
153
+		err = io.ErrUnexpectedEOF
154
+	}
155
+	return
156
+}
157
+
158
+// readHeader parses a packet header and returns an io.Reader which will return
159
+// the contents of the packet. See RFC 4880, section 4.2.
160
+func readHeader(r io.Reader) (tag packetType, length int64, contents io.Reader, err error) {
161
+	var buf [4]byte
162
+	_, err = io.ReadFull(r, buf[:1])
163
+	if err != nil {
164
+		return
165
+	}
166
+	if buf[0]&0x80 == 0 {
167
+		err = errors.StructuralError("tag byte does not have MSB set")
168
+		return
169
+	}
170
+	if buf[0]&0x40 == 0 {
171
+		// Old format packet
172
+		tag = packetType((buf[0] & 0x3f) >> 2)
173
+		lengthType := buf[0] & 3
174
+		if lengthType == 3 {
175
+			length = -1
176
+			contents = r
177
+			return
178
+		}
179
+		lengthBytes := 1 << lengthType
180
+		_, err = readFull(r, buf[0:lengthBytes])
181
+		if err != nil {
182
+			return
183
+		}
184
+		for i := 0; i < lengthBytes; i++ {
185
+			length <<= 8
186
+			length |= int64(buf[i])
187
+		}
188
+		contents = &spanReader{r, length}
189
+		return
190
+	}
191
+
192
+	// New format packet
193
+	tag = packetType(buf[0] & 0x3f)
194
+	length, isPartial, err := readLength(r)
195
+	if err != nil {
196
+		return
197
+	}
198
+	if isPartial {
199
+		contents = &partialLengthReader{
200
+			remaining: length,
201
+			isPartial: true,
202
+			r:         r,
203
+		}
204
+		length = -1
205
+	} else {
206
+		contents = &spanReader{r, length}
207
+	}
208
+	return
209
+}
210
+
211
+// serializeHeader writes an OpenPGP packet header to w. See RFC 4880, section
212
+// 4.2.
213
+func serializeHeader(w io.Writer, ptype packetType, length int) (err error) {
214
+	var buf [6]byte
215
+	var n int
216
+
217
+	buf[0] = 0x80 | 0x40 | byte(ptype)
218
+	if length < 192 {
219
+		buf[1] = byte(length)
220
+		n = 2
221
+	} else if length < 8384 {
222
+		length -= 192
223
+		buf[1] = 192 + byte(length>>8)
224
+		buf[2] = byte(length)
225
+		n = 3
226
+	} else {
227
+		buf[1] = 255
228
+		buf[2] = byte(length >> 24)
229
+		buf[3] = byte(length >> 16)
230
+		buf[4] = byte(length >> 8)
231
+		buf[5] = byte(length)
232
+		n = 6
233
+	}
234
+
235
+	_, err = w.Write(buf[:n])
236
+	return
237
+}
238
+
239
+// serializeStreamHeader writes an OpenPGP packet header to w where the
240
+// length of the packet is unknown. It returns a io.WriteCloser which can be
241
+// used to write the contents of the packet. See RFC 4880, section 4.2.
242
+func serializeStreamHeader(w io.WriteCloser, ptype packetType) (out io.WriteCloser, err error) {
243
+	var buf [1]byte
244
+	buf[0] = 0x80 | 0x40 | byte(ptype)
245
+	_, err = w.Write(buf[:])
246
+	if err != nil {
247
+		return
248
+	}
249
+	out = &partialLengthWriter{w: w}
250
+	return
251
+}
252
+
253
+// Packet represents an OpenPGP packet. Users are expected to try casting
254
+// instances of this interface to specific packet types.
255
+type Packet interface {
256
+	parse(io.Reader) error
257
+}
258
+
259
+// consumeAll reads from the given Reader until error, returning the number of
260
+// bytes read.
261
+func consumeAll(r io.Reader) (n int64, err error) {
262
+	var m int
263
+	var buf [1024]byte
264
+
265
+	for {
266
+		m, err = r.Read(buf[:])
267
+		n += int64(m)
268
+		if err == io.EOF {
269
+			err = nil
270
+			return
271
+		}
272
+		if err != nil {
273
+			return
274
+		}
275
+	}
276
+}
277
+
278
+// packetType represents the numeric ids of the different OpenPGP packet types. See
279
+// http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-2
280
+type packetType uint8
281
+
282
+const (
283
+	packetTypeEncryptedKey              packetType = 1
284
+	packetTypeSignature                 packetType = 2
285
+	packetTypeSymmetricKeyEncrypted     packetType = 3
286
+	packetTypeOnePassSignature          packetType = 4
287
+	packetTypePrivateKey                packetType = 5
288
+	packetTypePublicKey                 packetType = 6
289
+	packetTypePrivateSubkey             packetType = 7
290
+	packetTypeCompressed                packetType = 8
291
+	packetTypeSymmetricallyEncrypted    packetType = 9
292
+	packetTypeLiteralData               packetType = 11
293
+	packetTypeUserId                    packetType = 13
294
+	packetTypePublicSubkey              packetType = 14
295
+	packetTypeUserAttribute             packetType = 17
296
+	packetTypeSymmetricallyEncryptedMDC packetType = 18
297
+)
298
+
299
+// peekVersion detects the version of a public key packet about to
300
+// be read. A bufio.Reader at the original position of the io.Reader
301
+// is returned.
302
+func peekVersion(r io.Reader) (bufr *bufio.Reader, ver byte, err error) {
303
+	bufr = bufio.NewReader(r)
304
+	var verBuf []byte
305
+	if verBuf, err = bufr.Peek(1); err != nil {
306
+		return
307
+	}
308
+	ver = verBuf[0]
309
+	return
310
+}
311
+
312
+// Read reads a single OpenPGP packet from the given io.Reader. If there is an
313
+// error parsing a packet, the whole packet is consumed from the input.
314
+func Read(r io.Reader) (p Packet, err error) {
315
+	tag, _, contents, err := readHeader(r)
316
+	if err != nil {
317
+		return
318
+	}
319
+
320
+	switch tag {
321
+	case packetTypeEncryptedKey:
322
+		p = new(EncryptedKey)
323
+	case packetTypeSignature:
324
+		var version byte
325
+		// Detect signature version
326
+		if contents, version, err = peekVersion(contents); err != nil {
327
+			return
328
+		}
329
+		if version < 4 {
330
+			p = new(SignatureV3)
331
+		} else {
332
+			p = new(Signature)
333
+		}
334
+	case packetTypeSymmetricKeyEncrypted:
335
+		p = new(SymmetricKeyEncrypted)
336
+	case packetTypeOnePassSignature:
337
+		p = new(OnePassSignature)
338
+	case packetTypePrivateKey, packetTypePrivateSubkey:
339
+		pk := new(PrivateKey)
340
+		if tag == packetTypePrivateSubkey {
341
+			pk.IsSubkey = true
342
+		}
343
+		p = pk
344
+	case packetTypePublicKey, packetTypePublicSubkey:
345
+		var version byte
346
+		if contents, version, err = peekVersion(contents); err != nil {
347
+			return
348
+		}
349
+		isSubkey := tag == packetTypePublicSubkey
350
+		if version < 4 {
351
+			p = &PublicKeyV3{IsSubkey: isSubkey}
352
+		} else {
353
+			p = &PublicKey{IsSubkey: isSubkey}
354
+		}
355
+	case packetTypeCompressed:
356
+		p = new(Compressed)
357
+	case packetTypeSymmetricallyEncrypted:
358
+		p = new(SymmetricallyEncrypted)
359
+	case packetTypeLiteralData:
360
+		p = new(LiteralData)
361
+	case packetTypeUserId:
362
+		p = new(UserId)
363
+	case packetTypeUserAttribute:
364
+		p = new(UserAttribute)
365
+	case packetTypeSymmetricallyEncryptedMDC:
366
+		se := new(SymmetricallyEncrypted)
367
+		se.MDC = true
368
+		p = se
369
+	default:
370
+		err = errors.UnknownPacketTypeError(tag)
371
+	}
372
+	if p != nil {
373
+		err = p.parse(contents)
374
+	}
375
+	if err != nil {
376
+		consumeAll(contents)
377
+	}
378
+	return
379
+}
380
+
381
+// SignatureType represents the different semantic meanings of an OpenPGP
382
+// signature. See RFC 4880, section 5.2.1.
383
+type SignatureType uint8
384
+
385
+const (
386
+	SigTypeBinary            SignatureType = 0
387
+	SigTypeText                            = 1
388
+	SigTypeGenericCert                     = 0x10
389
+	SigTypePersonaCert                     = 0x11
390
+	SigTypeCasualCert                      = 0x12
391
+	SigTypePositiveCert                    = 0x13
392
+	SigTypeSubkeyBinding                   = 0x18
393
+	SigTypePrimaryKeyBinding               = 0x19
394
+	SigTypeDirectSignature                 = 0x1F
395
+	SigTypeKeyRevocation                   = 0x20
396
+	SigTypeSubkeyRevocation                = 0x28
397
+)
398
+
399
+// PublicKeyAlgorithm represents the different public key system specified for
400
+// OpenPGP. See
401
+// http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-12
402
+type PublicKeyAlgorithm uint8
403
+
404
+const (
405
+	PubKeyAlgoRSA            PublicKeyAlgorithm = 1
406
+	PubKeyAlgoRSAEncryptOnly PublicKeyAlgorithm = 2
407
+	PubKeyAlgoRSASignOnly    PublicKeyAlgorithm = 3
408
+	PubKeyAlgoElGamal        PublicKeyAlgorithm = 16
409
+	PubKeyAlgoDSA            PublicKeyAlgorithm = 17
410
+	// RFC 6637, Section 5.
411
+	PubKeyAlgoECDH  PublicKeyAlgorithm = 18
412
+	PubKeyAlgoECDSA PublicKeyAlgorithm = 19
413
+)
414
+
415
+// CanEncrypt returns true if it's possible to encrypt a message to a public
416
+// key of the given type.
417
+func (pka PublicKeyAlgorithm) CanEncrypt() bool {
418
+	switch pka {
419
+	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoElGamal:
420
+		return true
421
+	}
422
+	return false
423
+}
424
+
425
+// CanSign returns true if it's possible for a public key of the given type to
426
+// sign a message.
427
+func (pka PublicKeyAlgorithm) CanSign() bool {
428
+	switch pka {
429
+	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoDSA, PubKeyAlgoECDSA:
430
+		return true
431
+	}
432
+	return false
433
+}
434
+
435
+// CipherFunction represents the different block ciphers specified for OpenPGP. See
436
+// http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-13
437
+type CipherFunction uint8
438
+
439
+const (
440
+	Cipher3DES   CipherFunction = 2
441
+	CipherCAST5  CipherFunction = 3
442
+	CipherAES128 CipherFunction = 7
443
+	CipherAES192 CipherFunction = 8
444
+	CipherAES256 CipherFunction = 9
445
+)
446
+
447
+// KeySize returns the key size, in bytes, of cipher.
448
+func (cipher CipherFunction) KeySize() int {
449
+	switch cipher {
450
+	case Cipher3DES:
451
+		return 24
452
+	case CipherCAST5:
453
+		return cast5.KeySize
454
+	case CipherAES128:
455
+		return 16
456
+	case CipherAES192:
457
+		return 24
458
+	case CipherAES256:
459
+		return 32
460
+	}
461
+	return 0
462
+}
463
+
464
+// blockSize returns the block size, in bytes, of cipher.
465
+func (cipher CipherFunction) blockSize() int {
466
+	switch cipher {
467
+	case Cipher3DES:
468
+		return des.BlockSize
469
+	case CipherCAST5:
470
+		return 8
471
+	case CipherAES128, CipherAES192, CipherAES256:
472
+		return 16
473
+	}
474
+	return 0
475
+}
476
+
477
+// new returns a fresh instance of the given cipher.
478
+func (cipher CipherFunction) new(key []byte) (block cipher.Block) {
479
+	switch cipher {
480
+	case Cipher3DES:
481
+		block, _ = des.NewTripleDESCipher(key)
482
+	case CipherCAST5:
483
+		block, _ = cast5.NewCipher(key)
484
+	case CipherAES128, CipherAES192, CipherAES256:
485
+		block, _ = aes.NewCipher(key)
486
+	}
487
+	return
488
+}
489
+
490
+// readMPI reads a big integer from r. The bit length returned is the bit
491
+// length that was specified in r. This is preserved so that the integer can be
492
+// reserialized exactly.
493
+func readMPI(r io.Reader) (mpi []byte, bitLength uint16, err error) {
494
+	var buf [2]byte
495
+	_, err = readFull(r, buf[0:])
496
+	if err != nil {
497
+		return
498
+	}
499
+	bitLength = uint16(buf[0])<<8 | uint16(buf[1])
500
+	numBytes := (int(bitLength) + 7) / 8
501
+	mpi = make([]byte, numBytes)
502
+	_, err = readFull(r, mpi)
503
+	return
504
+}
505
+
506
+// mpiLength returns the length of the given *big.Int when serialized as an
507
+// MPI.
508
+func mpiLength(n *big.Int) (mpiLengthInBytes int) {
509
+	mpiLengthInBytes = 2 /* MPI length */
510
+	mpiLengthInBytes += (n.BitLen() + 7) / 8
511
+	return
512
+}
513
+
514
+// writeMPI serializes a big integer to w.
515
+func writeMPI(w io.Writer, bitLength uint16, mpiBytes []byte) (err error) {
516
+	_, err = w.Write([]byte{byte(bitLength >> 8), byte(bitLength)})
517
+	if err == nil {
518
+		_, err = w.Write(mpiBytes)
519
+	}
520
+	return
521
+}
522
+
523
+// writeBig serializes a *big.Int to w.
524
+func writeBig(w io.Writer, i *big.Int) error {
525
+	return writeMPI(w, uint16(i.BitLen()), i.Bytes())
526
+}
527
+
528
+// CompressionAlgo Represents the different compression algorithms
529
+// supported by OpenPGP (except for BZIP2, which is not currently
530
+// supported). See Section 9.3 of RFC 4880.
531
+type CompressionAlgo uint8
532
+
533
+const (
534
+	CompressionNone CompressionAlgo = 0
535
+	CompressionZIP  CompressionAlgo = 1
536
+	CompressionZLIB CompressionAlgo = 2
537
+)

+ 255
- 0
vendor/src/golang.org/x/crypto/openpgp/packet/packet_test.go 查看文件

@@ -0,0 +1,255 @@
1
+// Copyright 2011 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
+
5
+package packet
6
+
7
+import (
8
+	"bytes"
9
+	"encoding/hex"
10
+	"fmt"
11
+	"golang.org/x/crypto/openpgp/errors"
12
+	"io"
13
+	"io/ioutil"
14
+	"testing"
15
+)
16
+
17
+func TestReadFull(t *testing.T) {
18
+	var out [4]byte
19
+
20
+	b := bytes.NewBufferString("foo")
21
+	n, err := readFull(b, out[:3])
22
+	if n != 3 || err != nil {
23
+		t.Errorf("full read failed n:%d err:%s", n, err)
24
+	}
25
+
26
+	b = bytes.NewBufferString("foo")
27
+	n, err = readFull(b, out[:4])
28
+	if n != 3 || err != io.ErrUnexpectedEOF {
29
+		t.Errorf("partial read failed n:%d err:%s", n, err)
30
+	}
31
+
32
+	b = bytes.NewBuffer(nil)
33
+	n, err = readFull(b, out[:3])
34
+	if n != 0 || err != io.ErrUnexpectedEOF {
35
+		t.Errorf("empty read failed n:%d err:%s", n, err)
36
+	}
37
+}
38
+
39
+func readerFromHex(s string) io.Reader {
40
+	data, err := hex.DecodeString(s)
41
+	if err != nil {
42
+		panic("readerFromHex: bad input")
43
+	}
44
+	return bytes.NewBuffer(data)
45
+}
46
+
47
+var readLengthTests = []struct {
48
+	hexInput  string
49
+	length    int64
50
+	isPartial bool
51
+	err       error
52
+}{
53
+	{"", 0, false, io.ErrUnexpectedEOF},
54
+	{"1f", 31, false, nil},
55
+	{"c0", 0, false, io.ErrUnexpectedEOF},
56
+	{"c101", 256 + 1 + 192, false, nil},
57
+	{"e0", 1, true, nil},
58
+	{"e1", 2, true, nil},
59
+	{"e2", 4, true, nil},
60
+	{"ff", 0, false, io.ErrUnexpectedEOF},
61
+	{"ff00", 0, false, io.ErrUnexpectedEOF},
62
+	{"ff0000", 0, false, io.ErrUnexpectedEOF},
63
+	{"ff000000", 0, false, io.ErrUnexpectedEOF},
64
+	{"ff00000000", 0, false, nil},
65
+	{"ff01020304", 16909060, false, nil},
66
+}
67
+
68
+func TestReadLength(t *testing.T) {
69
+	for i, test := range readLengthTests {
70
+		length, isPartial, err := readLength(readerFromHex(test.hexInput))
71
+		if test.err != nil {
72
+			if err != test.err {
73
+				t.Errorf("%d: expected different error got:%s want:%s", i, err, test.err)
74
+			}
75
+			continue
76
+		}
77
+		if err != nil {
78
+			t.Errorf("%d: unexpected error: %s", i, err)
79
+			continue
80
+		}
81
+		if length != test.length || isPartial != test.isPartial {
82
+			t.Errorf("%d: bad result got:(%d,%t) want:(%d,%t)", i, length, isPartial, test.length, test.isPartial)
83
+		}
84
+	}
85
+}
86
+
87
+var partialLengthReaderTests = []struct {
88
+	hexInput  string
89
+	err       error
90
+	hexOutput string
91
+}{
92
+	{"e0", io.ErrUnexpectedEOF, ""},
93
+	{"e001", io.ErrUnexpectedEOF, ""},
94
+	{"e0010102", nil, "0102"},
95
+	{"ff00000000", nil, ""},
96
+	{"e10102e1030400", nil, "01020304"},
97
+	{"e101", io.ErrUnexpectedEOF, ""},
98
+}
99
+
100
+func TestPartialLengthReader(t *testing.T) {
101
+	for i, test := range partialLengthReaderTests {
102
+		r := &partialLengthReader{readerFromHex(test.hexInput), 0, true}
103
+		out, err := ioutil.ReadAll(r)
104
+		if test.err != nil {
105
+			if err != test.err {
106
+				t.Errorf("%d: expected different error got:%s want:%s", i, err, test.err)
107
+			}
108
+			continue
109
+		}
110
+		if err != nil {
111
+			t.Errorf("%d: unexpected error: %s", i, err)
112
+			continue
113
+		}
114
+
115
+		got := fmt.Sprintf("%x", out)
116
+		if got != test.hexOutput {
117
+			t.Errorf("%d: got:%s want:%s", i, test.hexOutput, got)
118
+		}
119
+	}
120
+}
121
+
122
+var readHeaderTests = []struct {
123
+	hexInput        string
124
+	structuralError bool
125
+	unexpectedEOF   bool
126
+	tag             int
127
+	length          int64
128
+	hexOutput       string
129
+}{
130
+	{"", false, false, 0, 0, ""},
131
+	{"7f", true, false, 0, 0, ""},
132
+
133
+	// Old format headers
134
+	{"80", false, true, 0, 0, ""},
135
+	{"8001", false, true, 0, 1, ""},
136
+	{"800102", false, false, 0, 1, "02"},
137
+	{"81000102", false, false, 0, 1, "02"},
138
+	{"820000000102", false, false, 0, 1, "02"},
139
+	{"860000000102", false, false, 1, 1, "02"},
140
+	{"83010203", false, false, 0, -1, "010203"},
141
+
142
+	// New format headers
143
+	{"c0", false, true, 0, 0, ""},
144
+	{"c000", false, false, 0, 0, ""},
145
+	{"c00102", false, false, 0, 1, "02"},
146
+	{"c0020203", false, false, 0, 2, "0203"},
147
+	{"c00202", false, true, 0, 2, ""},
148
+	{"c3020203", false, false, 3, 2, "0203"},
149
+}
150
+
151
+func TestReadHeader(t *testing.T) {
152
+	for i, test := range readHeaderTests {
153
+		tag, length, contents, err := readHeader(readerFromHex(test.hexInput))
154
+		if test.structuralError {
155
+			if _, ok := err.(errors.StructuralError); ok {
156
+				continue
157
+			}
158
+			t.Errorf("%d: expected StructuralError, got:%s", i, err)
159
+			continue
160
+		}
161
+		if err != nil {
162
+			if len(test.hexInput) == 0 && err == io.EOF {
163
+				continue
164
+			}
165
+			if !test.unexpectedEOF || err != io.ErrUnexpectedEOF {
166
+				t.Errorf("%d: unexpected error from readHeader: %s", i, err)
167
+			}
168
+			continue
169
+		}
170
+		if int(tag) != test.tag || length != test.length {
171
+			t.Errorf("%d: got:(%d,%d) want:(%d,%d)", i, int(tag), length, test.tag, test.length)
172
+			continue
173
+		}
174
+
175
+		body, err := ioutil.ReadAll(contents)
176
+		if err != nil {
177
+			if !test.unexpectedEOF || err != io.ErrUnexpectedEOF {
178
+				t.Errorf("%d: unexpected error from contents: %s", i, err)
179
+			}
180
+			continue
181
+		}
182
+		if test.unexpectedEOF {
183
+			t.Errorf("%d: expected ErrUnexpectedEOF from contents but got no error", i)
184
+			continue
185
+		}
186
+		got := fmt.Sprintf("%x", body)
187
+		if got != test.hexOutput {
188
+			t.Errorf("%d: got:%s want:%s", i, got, test.hexOutput)
189
+		}
190
+	}
191
+}
192
+
193
+func TestSerializeHeader(t *testing.T) {
194
+	tag := packetTypePublicKey
195
+	lengths := []int{0, 1, 2, 64, 192, 193, 8000, 8384, 8385, 10000}
196
+
197
+	for _, length := range lengths {
198
+		buf := bytes.NewBuffer(nil)
199
+		serializeHeader(buf, tag, length)
200
+		tag2, length2, _, err := readHeader(buf)
201
+		if err != nil {
202
+			t.Errorf("length %d, err: %s", length, err)
203
+		}
204
+		if tag2 != tag {
205
+			t.Errorf("length %d, tag incorrect (got %d, want %d)", length, tag2, tag)
206
+		}
207
+		if int(length2) != length {
208
+			t.Errorf("length %d, length incorrect (got %d)", length, length2)
209
+		}
210
+	}
211
+}
212
+
213
+func TestPartialLengths(t *testing.T) {
214
+	buf := bytes.NewBuffer(nil)
215
+	w := new(partialLengthWriter)
216
+	w.w = noOpCloser{buf}
217
+
218
+	const maxChunkSize = 64
219
+
220
+	var b [maxChunkSize]byte
221
+	var n uint8
222
+	for l := 1; l <= maxChunkSize; l++ {
223
+		for i := 0; i < l; i++ {
224
+			b[i] = n
225
+			n++
226
+		}
227
+		m, err := w.Write(b[:l])
228
+		if m != l {
229
+			t.Errorf("short write got: %d want: %d", m, l)
230
+		}
231
+		if err != nil {
232
+			t.Errorf("error from write: %s", err)
233
+		}
234
+	}
235
+	w.Close()
236
+
237
+	want := (maxChunkSize * (maxChunkSize + 1)) / 2
238
+	copyBuf := bytes.NewBuffer(nil)
239
+	r := &partialLengthReader{buf, 0, true}
240
+	m, err := io.Copy(copyBuf, r)
241
+	if m != int64(want) {
242
+		t.Errorf("short copy got: %d want: %d", m, want)
243
+	}
244
+	if err != nil {
245
+		t.Errorf("error from copy: %s", err)
246
+	}
247
+
248
+	copyBytes := copyBuf.Bytes()
249
+	for i := 0; i < want; i++ {
250
+		if copyBytes[i] != uint8(i) {
251
+			t.Errorf("bad pattern in copy at %d", i)
252
+			break
253
+		}
254
+	}
255
+}

+ 380
- 0
vendor/src/golang.org/x/crypto/openpgp/packet/private_key.go 查看文件

@@ -0,0 +1,380 @@
1
+// Copyright 2011 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
+
5
+package packet
6
+
7
+import (
8
+	"bytes"
9
+	"crypto"
10
+	"crypto/cipher"
11
+	"crypto/dsa"
12
+	"crypto/ecdsa"
13
+	"crypto/rsa"
14
+	"crypto/sha1"
15
+	"io"
16
+	"io/ioutil"
17
+	"math/big"
18
+	"strconv"
19
+	"time"
20
+
21
+	"golang.org/x/crypto/openpgp/elgamal"
22
+	"golang.org/x/crypto/openpgp/errors"
23
+	"golang.org/x/crypto/openpgp/s2k"
24
+)
25
+
26
+// PrivateKey represents a possibly encrypted private key. See RFC 4880,
27
+// section 5.5.3.
28
+type PrivateKey struct {
29
+	PublicKey
30
+	Encrypted     bool // if true then the private key is unavailable until Decrypt has been called.
31
+	encryptedData []byte
32
+	cipher        CipherFunction
33
+	s2k           func(out, in []byte)
34
+	PrivateKey    interface{} // An *{rsa|dsa|ecdsa}.PrivateKey or a crypto.Signer.
35
+	sha1Checksum  bool
36
+	iv            []byte
37
+}
38
+
39
+func NewRSAPrivateKey(currentTime time.Time, priv *rsa.PrivateKey) *PrivateKey {
40
+	pk := new(PrivateKey)
41
+	pk.PublicKey = *NewRSAPublicKey(currentTime, &priv.PublicKey)
42
+	pk.PrivateKey = priv
43
+	return pk
44
+}
45
+
46
+func NewDSAPrivateKey(currentTime time.Time, priv *dsa.PrivateKey) *PrivateKey {
47
+	pk := new(PrivateKey)
48
+	pk.PublicKey = *NewDSAPublicKey(currentTime, &priv.PublicKey)
49
+	pk.PrivateKey = priv
50
+	return pk
51
+}
52
+
53
+func NewElGamalPrivateKey(currentTime time.Time, priv *elgamal.PrivateKey) *PrivateKey {
54
+	pk := new(PrivateKey)
55
+	pk.PublicKey = *NewElGamalPublicKey(currentTime, &priv.PublicKey)
56
+	pk.PrivateKey = priv
57
+	return pk
58
+}
59
+
60
+func NewECDSAPrivateKey(currentTime time.Time, priv *ecdsa.PrivateKey) *PrivateKey {
61
+	pk := new(PrivateKey)
62
+	pk.PublicKey = *NewECDSAPublicKey(currentTime, &priv.PublicKey)
63
+	pk.PrivateKey = priv
64
+	return pk
65
+}
66
+
67
+// NewSignerPrivateKey creates a sign-only PrivateKey from a crypto.Signer that
68
+// implements RSA or ECDSA.
69
+func NewSignerPrivateKey(currentTime time.Time, signer crypto.Signer) *PrivateKey {
70
+	pk := new(PrivateKey)
71
+	switch pubkey := signer.Public().(type) {
72
+	case rsa.PublicKey:
73
+		pk.PublicKey = *NewRSAPublicKey(currentTime, &pubkey)
74
+		pk.PubKeyAlgo = PubKeyAlgoRSASignOnly
75
+	case ecdsa.PublicKey:
76
+		pk.PublicKey = *NewECDSAPublicKey(currentTime, &pubkey)
77
+	default:
78
+		panic("openpgp: unknown crypto.Signer type in NewSignerPrivateKey")
79
+	}
80
+	pk.PrivateKey = signer
81
+	return pk
82
+}
83
+
84
+func (pk *PrivateKey) parse(r io.Reader) (err error) {
85
+	err = (&pk.PublicKey).parse(r)
86
+	if err != nil {
87
+		return
88
+	}
89
+	var buf [1]byte
90
+	_, err = readFull(r, buf[:])
91
+	if err != nil {
92
+		return
93
+	}
94
+
95
+	s2kType := buf[0]
96
+
97
+	switch s2kType {
98
+	case 0:
99
+		pk.s2k = nil
100
+		pk.Encrypted = false
101
+	case 254, 255:
102
+		_, err = readFull(r, buf[:])
103
+		if err != nil {
104
+			return
105
+		}
106
+		pk.cipher = CipherFunction(buf[0])
107
+		pk.Encrypted = true
108
+		pk.s2k, err = s2k.Parse(r)
109
+		if err != nil {
110
+			return
111
+		}
112
+		if s2kType == 254 {
113
+			pk.sha1Checksum = true
114
+		}
115
+	default:
116
+		return errors.UnsupportedError("deprecated s2k function in private key")
117
+	}
118
+
119
+	if pk.Encrypted {
120
+		blockSize := pk.cipher.blockSize()
121
+		if blockSize == 0 {
122
+			return errors.UnsupportedError("unsupported cipher in private key: " + strconv.Itoa(int(pk.cipher)))
123
+		}
124
+		pk.iv = make([]byte, blockSize)
125
+		_, err = readFull(r, pk.iv)
126
+		if err != nil {
127
+			return
128
+		}
129
+	}
130
+
131
+	pk.encryptedData, err = ioutil.ReadAll(r)
132
+	if err != nil {
133
+		return
134
+	}
135
+
136
+	if !pk.Encrypted {
137
+		return pk.parsePrivateKey(pk.encryptedData)
138
+	}
139
+
140
+	return
141
+}
142
+
143
+func mod64kHash(d []byte) uint16 {
144
+	var h uint16
145
+	for _, b := range d {
146
+		h += uint16(b)
147
+	}
148
+	return h
149
+}
150
+
151
+func (pk *PrivateKey) Serialize(w io.Writer) (err error) {
152
+	// TODO(agl): support encrypted private keys
153
+	buf := bytes.NewBuffer(nil)
154
+	err = pk.PublicKey.serializeWithoutHeaders(buf)
155
+	if err != nil {
156
+		return
157
+	}
158
+	buf.WriteByte(0 /* no encryption */)
159
+
160
+	privateKeyBuf := bytes.NewBuffer(nil)
161
+
162
+	switch priv := pk.PrivateKey.(type) {
163
+	case *rsa.PrivateKey:
164
+		err = serializeRSAPrivateKey(privateKeyBuf, priv)
165
+	case *dsa.PrivateKey:
166
+		err = serializeDSAPrivateKey(privateKeyBuf, priv)
167
+	case *elgamal.PrivateKey:
168
+		err = serializeElGamalPrivateKey(privateKeyBuf, priv)
169
+	case *ecdsa.PrivateKey:
170
+		err = serializeECDSAPrivateKey(privateKeyBuf, priv)
171
+	default:
172
+		err = errors.InvalidArgumentError("unknown private key type")
173
+	}
174
+	if err != nil {
175
+		return
176
+	}
177
+
178
+	ptype := packetTypePrivateKey
179
+	contents := buf.Bytes()
180
+	privateKeyBytes := privateKeyBuf.Bytes()
181
+	if pk.IsSubkey {
182
+		ptype = packetTypePrivateSubkey
183
+	}
184
+	err = serializeHeader(w, ptype, len(contents)+len(privateKeyBytes)+2)
185
+	if err != nil {
186
+		return
187
+	}
188
+	_, err = w.Write(contents)
189
+	if err != nil {
190
+		return
191
+	}
192
+	_, err = w.Write(privateKeyBytes)
193
+	if err != nil {
194
+		return
195
+	}
196
+
197
+	checksum := mod64kHash(privateKeyBytes)
198
+	var checksumBytes [2]byte
199
+	checksumBytes[0] = byte(checksum >> 8)
200
+	checksumBytes[1] = byte(checksum)
201
+	_, err = w.Write(checksumBytes[:])
202
+
203
+	return
204
+}
205
+
206
+func serializeRSAPrivateKey(w io.Writer, priv *rsa.PrivateKey) error {
207
+	err := writeBig(w, priv.D)
208
+	if err != nil {
209
+		return err
210
+	}
211
+	err = writeBig(w, priv.Primes[1])
212
+	if err != nil {
213
+		return err
214
+	}
215
+	err = writeBig(w, priv.Primes[0])
216
+	if err != nil {
217
+		return err
218
+	}
219
+	return writeBig(w, priv.Precomputed.Qinv)
220
+}
221
+
222
+func serializeDSAPrivateKey(w io.Writer, priv *dsa.PrivateKey) error {
223
+	return writeBig(w, priv.X)
224
+}
225
+
226
+func serializeElGamalPrivateKey(w io.Writer, priv *elgamal.PrivateKey) error {
227
+	return writeBig(w, priv.X)
228
+}
229
+
230
+func serializeECDSAPrivateKey(w io.Writer, priv *ecdsa.PrivateKey) error {
231
+	return writeBig(w, priv.D)
232
+}
233
+
234
+// Decrypt decrypts an encrypted private key using a passphrase.
235
+func (pk *PrivateKey) Decrypt(passphrase []byte) error {
236
+	if !pk.Encrypted {
237
+		return nil
238
+	}
239
+
240
+	key := make([]byte, pk.cipher.KeySize())
241
+	pk.s2k(key, passphrase)
242
+	block := pk.cipher.new(key)
243
+	cfb := cipher.NewCFBDecrypter(block, pk.iv)
244
+
245
+	data := make([]byte, len(pk.encryptedData))
246
+	cfb.XORKeyStream(data, pk.encryptedData)
247
+
248
+	if pk.sha1Checksum {
249
+		if len(data) < sha1.Size {
250
+			return errors.StructuralError("truncated private key data")
251
+		}
252
+		h := sha1.New()
253
+		h.Write(data[:len(data)-sha1.Size])
254
+		sum := h.Sum(nil)
255
+		if !bytes.Equal(sum, data[len(data)-sha1.Size:]) {
256
+			return errors.StructuralError("private key checksum failure")
257
+		}
258
+		data = data[:len(data)-sha1.Size]
259
+	} else {
260
+		if len(data) < 2 {
261
+			return errors.StructuralError("truncated private key data")
262
+		}
263
+		var sum uint16
264
+		for i := 0; i < len(data)-2; i++ {
265
+			sum += uint16(data[i])
266
+		}
267
+		if data[len(data)-2] != uint8(sum>>8) ||
268
+			data[len(data)-1] != uint8(sum) {
269
+			return errors.StructuralError("private key checksum failure")
270
+		}
271
+		data = data[:len(data)-2]
272
+	}
273
+
274
+	return pk.parsePrivateKey(data)
275
+}
276
+
277
+func (pk *PrivateKey) parsePrivateKey(data []byte) (err error) {
278
+	switch pk.PublicKey.PubKeyAlgo {
279
+	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoRSAEncryptOnly:
280
+		return pk.parseRSAPrivateKey(data)
281
+	case PubKeyAlgoDSA:
282
+		return pk.parseDSAPrivateKey(data)
283
+	case PubKeyAlgoElGamal:
284
+		return pk.parseElGamalPrivateKey(data)
285
+	case PubKeyAlgoECDSA:
286
+		return pk.parseECDSAPrivateKey(data)
287
+	}
288
+	panic("impossible")
289
+}
290
+
291
+func (pk *PrivateKey) parseRSAPrivateKey(data []byte) (err error) {
292
+	rsaPub := pk.PublicKey.PublicKey.(*rsa.PublicKey)
293
+	rsaPriv := new(rsa.PrivateKey)
294
+	rsaPriv.PublicKey = *rsaPub
295
+
296
+	buf := bytes.NewBuffer(data)
297
+	d, _, err := readMPI(buf)
298
+	if err != nil {
299
+		return
300
+	}
301
+	p, _, err := readMPI(buf)
302
+	if err != nil {
303
+		return
304
+	}
305
+	q, _, err := readMPI(buf)
306
+	if err != nil {
307
+		return
308
+	}
309
+
310
+	rsaPriv.D = new(big.Int).SetBytes(d)
311
+	rsaPriv.Primes = make([]*big.Int, 2)
312
+	rsaPriv.Primes[0] = new(big.Int).SetBytes(p)
313
+	rsaPriv.Primes[1] = new(big.Int).SetBytes(q)
314
+	if err := rsaPriv.Validate(); err != nil {
315
+		return err
316
+	}
317
+	rsaPriv.Precompute()
318
+	pk.PrivateKey = rsaPriv
319
+	pk.Encrypted = false
320
+	pk.encryptedData = nil
321
+
322
+	return nil
323
+}
324
+
325
+func (pk *PrivateKey) parseDSAPrivateKey(data []byte) (err error) {
326
+	dsaPub := pk.PublicKey.PublicKey.(*dsa.PublicKey)
327
+	dsaPriv := new(dsa.PrivateKey)
328
+	dsaPriv.PublicKey = *dsaPub
329
+
330
+	buf := bytes.NewBuffer(data)
331
+	x, _, err := readMPI(buf)
332
+	if err != nil {
333
+		return
334
+	}
335
+
336
+	dsaPriv.X = new(big.Int).SetBytes(x)
337
+	pk.PrivateKey = dsaPriv
338
+	pk.Encrypted = false
339
+	pk.encryptedData = nil
340
+
341
+	return nil
342
+}
343
+
344
+func (pk *PrivateKey) parseElGamalPrivateKey(data []byte) (err error) {
345
+	pub := pk.PublicKey.PublicKey.(*elgamal.PublicKey)
346
+	priv := new(elgamal.PrivateKey)
347
+	priv.PublicKey = *pub
348
+
349
+	buf := bytes.NewBuffer(data)
350
+	x, _, err := readMPI(buf)
351
+	if err != nil {
352
+		return
353
+	}
354
+
355
+	priv.X = new(big.Int).SetBytes(x)
356
+	pk.PrivateKey = priv
357
+	pk.Encrypted = false
358
+	pk.encryptedData = nil
359
+
360
+	return nil
361
+}
362
+
363
+func (pk *PrivateKey) parseECDSAPrivateKey(data []byte) (err error) {
364
+	ecdsaPub := pk.PublicKey.PublicKey.(*ecdsa.PublicKey)
365
+
366
+	buf := bytes.NewBuffer(data)
367
+	d, _, err := readMPI(buf)
368
+	if err != nil {
369
+		return
370
+	}
371
+
372
+	pk.PrivateKey = &ecdsa.PrivateKey{
373
+		PublicKey: *ecdsaPub,
374
+		D:         new(big.Int).SetBytes(d),
375
+	}
376
+	pk.Encrypted = false
377
+	pk.encryptedData = nil
378
+
379
+	return nil
380
+}

+ 270
- 0
vendor/src/golang.org/x/crypto/openpgp/packet/private_key_test.go 查看文件

@@ -0,0 +1,270 @@
1
+// Copyright 2011 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
+
5
+package packet
6
+
7
+import (
8
+	"bytes"
9
+	"crypto"
10
+	"crypto/ecdsa"
11
+	"crypto/elliptic"
12
+	"crypto/rand"
13
+	"crypto/rsa"
14
+	"crypto/x509"
15
+	"encoding/hex"
16
+	"hash"
17
+	"io"
18
+	"testing"
19
+	"time"
20
+)
21
+
22
+var privateKeyTests = []struct {
23
+	privateKeyHex string
24
+	creationTime  time.Time
25
+}{
26
+	{
27
+		privKeyRSAHex,
28
+		time.Unix(0x4cc349a8, 0),
29
+	},
30
+	{
31
+		privKeyElGamalHex,
32
+		time.Unix(0x4df9ee1a, 0),
33
+	},
34
+}
35
+
36
+func TestPrivateKeyRead(t *testing.T) {
37
+	for i, test := range privateKeyTests {
38
+		packet, err := Read(readerFromHex(test.privateKeyHex))
39
+		if err != nil {
40
+			t.Errorf("#%d: failed to parse: %s", i, err)
41
+			continue
42
+		}
43
+
44
+		privKey := packet.(*PrivateKey)
45
+
46
+		if !privKey.Encrypted {
47
+			t.Errorf("#%d: private key isn't encrypted", i)
48
+			continue
49
+		}
50
+
51
+		err = privKey.Decrypt([]byte("wrong password"))
52
+		if err == nil {
53
+			t.Errorf("#%d: decrypted with incorrect key", i)
54
+			continue
55
+		}
56
+
57
+		err = privKey.Decrypt([]byte("testing"))
58
+		if err != nil {
59
+			t.Errorf("#%d: failed to decrypt: %s", i, err)
60
+			continue
61
+		}
62
+
63
+		if !privKey.CreationTime.Equal(test.creationTime) || privKey.Encrypted {
64
+			t.Errorf("#%d: bad result, got: %#v", i, privKey)
65
+		}
66
+	}
67
+}
68
+
69
+func populateHash(hashFunc crypto.Hash, msg []byte) (hash.Hash, error) {
70
+	h := hashFunc.New()
71
+	if _, err := h.Write(msg); err != nil {
72
+		return nil, err
73
+	}
74
+	return h, nil
75
+}
76
+
77
+func TestRSAPrivateKey(t *testing.T) {
78
+	privKeyDER, _ := hex.DecodeString(pkcs1PrivKeyHex)
79
+	rsaPriv, err := x509.ParsePKCS1PrivateKey(privKeyDER)
80
+	if err != nil {
81
+		t.Fatal(err)
82
+	}
83
+
84
+	var buf bytes.Buffer
85
+	if err := NewRSAPrivateKey(time.Now(), rsaPriv).Serialize(&buf); err != nil {
86
+		t.Fatal(err)
87
+	}
88
+
89
+	p, err := Read(&buf)
90
+	if err != nil {
91
+		t.Fatal(err)
92
+	}
93
+
94
+	priv, ok := p.(*PrivateKey)
95
+	if !ok {
96
+		t.Fatal("didn't parse private key")
97
+	}
98
+
99
+	sig := &Signature{
100
+		PubKeyAlgo: PubKeyAlgoRSA,
101
+		Hash:       crypto.SHA256,
102
+	}
103
+	msg := []byte("Hello World!")
104
+
105
+	h, err := populateHash(sig.Hash, msg)
106
+	if err != nil {
107
+		t.Fatal(err)
108
+	}
109
+	if err := sig.Sign(h, priv, nil); err != nil {
110
+		t.Fatal(err)
111
+	}
112
+
113
+	if h, err = populateHash(sig.Hash, msg); err != nil {
114
+		t.Fatal(err)
115
+	}
116
+	if err := priv.VerifySignature(h, sig); err != nil {
117
+		t.Fatal(err)
118
+	}
119
+}
120
+
121
+func TestECDSAPrivateKey(t *testing.T) {
122
+	ecdsaPriv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
123
+	if err != nil {
124
+		t.Fatal(err)
125
+	}
126
+
127
+	var buf bytes.Buffer
128
+	if err := NewECDSAPrivateKey(time.Now(), ecdsaPriv).Serialize(&buf); err != nil {
129
+		t.Fatal(err)
130
+	}
131
+
132
+	p, err := Read(&buf)
133
+	if err != nil {
134
+		t.Fatal(err)
135
+	}
136
+
137
+	priv, ok := p.(*PrivateKey)
138
+	if !ok {
139
+		t.Fatal("didn't parse private key")
140
+	}
141
+
142
+	sig := &Signature{
143
+		PubKeyAlgo: PubKeyAlgoECDSA,
144
+		Hash:       crypto.SHA256,
145
+	}
146
+	msg := []byte("Hello World!")
147
+
148
+	h, err := populateHash(sig.Hash, msg)
149
+	if err != nil {
150
+		t.Fatal(err)
151
+	}
152
+	if err := sig.Sign(h, priv, nil); err != nil {
153
+		t.Fatal(err)
154
+	}
155
+
156
+	if h, err = populateHash(sig.Hash, msg); err != nil {
157
+		t.Fatal(err)
158
+	}
159
+	if err := priv.VerifySignature(h, sig); err != nil {
160
+		t.Fatal(err)
161
+	}
162
+}
163
+
164
+type rsaSigner struct {
165
+	priv *rsa.PrivateKey
166
+}
167
+
168
+func (s *rsaSigner) Public() crypto.PublicKey {
169
+	return s.priv.PublicKey
170
+}
171
+
172
+func (s *rsaSigner) Sign(rand io.Reader, msg []byte, opts crypto.SignerOpts) ([]byte, error) {
173
+	return s.priv.Sign(rand, msg, opts)
174
+}
175
+
176
+func TestRSASignerPrivateKey(t *testing.T) {
177
+	rsaPriv, err := rsa.GenerateKey(rand.Reader, 1024)
178
+	if err != nil {
179
+		t.Fatal(err)
180
+	}
181
+
182
+	priv := NewSignerPrivateKey(time.Now(), &rsaSigner{rsaPriv})
183
+
184
+	if priv.PubKeyAlgo != PubKeyAlgoRSASignOnly {
185
+		t.Fatal("NewSignerPrivateKey should have made a sign-only RSA private key")
186
+	}
187
+
188
+	sig := &Signature{
189
+		PubKeyAlgo: PubKeyAlgoRSASignOnly,
190
+		Hash:       crypto.SHA256,
191
+	}
192
+	msg := []byte("Hello World!")
193
+
194
+	h, err := populateHash(sig.Hash, msg)
195
+	if err != nil {
196
+		t.Fatal(err)
197
+	}
198
+	if err := sig.Sign(h, priv, nil); err != nil {
199
+		t.Fatal(err)
200
+	}
201
+
202
+	if h, err = populateHash(sig.Hash, msg); err != nil {
203
+		t.Fatal(err)
204
+	}
205
+	if err := priv.VerifySignature(h, sig); err != nil {
206
+		t.Fatal(err)
207
+	}
208
+}
209
+
210
+type ecdsaSigner struct {
211
+	priv *ecdsa.PrivateKey
212
+}
213
+
214
+func (s *ecdsaSigner) Public() crypto.PublicKey {
215
+	return s.priv.PublicKey
216
+}
217
+
218
+func (s *ecdsaSigner) Sign(rand io.Reader, msg []byte, opts crypto.SignerOpts) ([]byte, error) {
219
+	return s.priv.Sign(rand, msg, opts)
220
+}
221
+
222
+func TestECDSASignerPrivateKey(t *testing.T) {
223
+	ecdsaPriv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
224
+	if err != nil {
225
+		t.Fatal(err)
226
+	}
227
+
228
+	priv := NewSignerPrivateKey(time.Now(), &ecdsaSigner{ecdsaPriv})
229
+
230
+	if priv.PubKeyAlgo != PubKeyAlgoECDSA {
231
+		t.Fatal("NewSignerPrivateKey should have made an ECSDA private key")
232
+	}
233
+
234
+	sig := &Signature{
235
+		PubKeyAlgo: PubKeyAlgoECDSA,
236
+		Hash:       crypto.SHA256,
237
+	}
238
+	msg := []byte("Hello World!")
239
+
240
+	h, err := populateHash(sig.Hash, msg)
241
+	if err != nil {
242
+		t.Fatal(err)
243
+	}
244
+	if err := sig.Sign(h, priv, nil); err != nil {
245
+		t.Fatal(err)
246
+	}
247
+
248
+	if h, err = populateHash(sig.Hash, msg); err != nil {
249
+		t.Fatal(err)
250
+	}
251
+	if err := priv.VerifySignature(h, sig); err != nil {
252
+		t.Fatal(err)
253
+	}
254
+}
255
+
256
+func TestIssue11505(t *testing.T) {
257
+	// parsing a rsa private key with p or q == 1 used to panic due to a divide by zero
258
+	_, _ = Read(readerFromHex("9c3004303030300100000011303030000000000000010130303030303030303030303030303030303030303030303030303030303030303030303030303030303030"))
259
+}
260
+
261
+// Generated with `gpg --export-secret-keys "Test Key 2"`
262
+const privKeyRSAHex = "9501fe044cc349a8010400b70ca0010e98c090008d45d1ee8f9113bd5861fd57b88bacb7c68658747663f1e1a3b5a98f32fda6472373c024b97359cd2efc88ff60f77751adfbf6af5e615e6a1408cfad8bf0cea30b0d5f53aa27ad59089ba9b15b7ebc2777a25d7b436144027e3bcd203909f147d0e332b240cf63d3395f5dfe0df0a6c04e8655af7eacdf0011010001fe0303024a252e7d475fd445607de39a265472aa74a9320ba2dac395faa687e9e0336aeb7e9a7397e511b5afd9dc84557c80ac0f3d4d7bfec5ae16f20d41c8c84a04552a33870b930420e230e179564f6d19bb153145e76c33ae993886c388832b0fa042ddda7f133924f3854481533e0ede31d51278c0519b29abc3bf53da673e13e3e1214b52413d179d7f66deee35cac8eacb060f78379d70ef4af8607e68131ff529439668fc39c9ce6dfef8a5ac234d234802cbfb749a26107db26406213ae5c06d4673253a3cbee1fcbae58d6ab77e38d6e2c0e7c6317c48e054edadb5a40d0d48acb44643d998139a8a66bb820be1f3f80185bc777d14b5954b60effe2448a036d565c6bc0b915fcea518acdd20ab07bc1529f561c58cd044f723109b93f6fd99f876ff891d64306b5d08f48bab59f38695e9109c4dec34013ba3153488ce070268381ba923ee1eb77125b36afcb4347ec3478c8f2735b06ef17351d872e577fa95d0c397c88c71b59629a36aec"
263
+
264
+// Generated by `gpg --export-secret-keys` followed by a manual extraction of
265
+// the ElGamal subkey from the packets.
266
+const privKeyElGamalHex = "9d0157044df9ee1a100400eb8e136a58ec39b582629cdadf830bc64e0a94ed8103ca8bb247b27b11b46d1d25297ef4bcc3071785ba0c0bedfe89eabc5287fcc0edf81ab5896c1c8e4b20d27d79813c7aede75320b33eaeeaa586edc00fd1036c10133e6ba0ff277245d0d59d04b2b3421b7244aca5f4a8d870c6f1c1fbff9e1c26699a860b9504f35ca1d700030503fd1ededd3b840795be6d9ccbe3c51ee42e2f39233c432b831ddd9c4e72b7025a819317e47bf94f9ee316d7273b05d5fcf2999c3a681f519b1234bbfa6d359b4752bd9c3f77d6b6456cde152464763414ca130f4e91d91041432f90620fec0e6d6b5116076c2985d5aeaae13be492b9b329efcaf7ee25120159a0a30cd976b42d7afe030302dae7eb80db744d4960c4df930d57e87fe81412eaace9f900e6c839817a614ddb75ba6603b9417c33ea7b6c93967dfa2bcff3fa3c74a5ce2c962db65b03aece14c96cbd0038fc"
267
+
268
+// pkcs1PrivKeyHex is a PKCS#1, RSA private key.
269
+// Generated by `openssl genrsa 1024 | openssl rsa -outform DER  | xxd -p`
270
+const pkcs1PrivKeyHex = "3082025d02010002818100e98edfa1c3b35884a54d0b36a6a603b0290fa85e49e30fa23fc94fef9c6790bc4849928607aa48d809da326fb42a969d06ad756b98b9c1a90f5d4a2b6d0ac05953c97f4da3120164a21a679793ce181c906dc01d235cc085ddcdf6ea06c389b6ab8885dfd685959e693138856a68a7e5db263337ff82a088d583a897cf2d59e9020301000102818100b6d5c9eb70b02d5369b3ee5b520a14490b5bde8a317d36f7e4c74b7460141311d1e5067735f8f01d6f5908b2b96fbd881f7a1ab9a84d82753e39e19e2d36856be960d05ac9ef8e8782ea1b6d65aee28fdfe1d61451e8cff0adfe84322f12cf455028b581cf60eb9e0e140ba5d21aeba6c2634d7c65318b9a665fc01c3191ca21024100fa5e818da3705b0fa33278bb28d4b6f6050388af2d4b75ec9375dd91ccf2e7d7068086a8b82a8f6282e4fbbdb8a7f2622eb97295249d87acea7f5f816f54d347024100eecf9406d7dc49cdfb95ab1eff4064de84c7a30f64b2798936a0d2018ba9eb52e4b636f82e96c49cc63b80b675e91e40d1b2e4017d4b9adaf33ab3d9cf1c214f024100c173704ace742c082323066226a4655226819a85304c542b9dacbeacbf5d1881ee863485fcf6f59f3a604f9b42289282067447f2b13dfeed3eab7851fc81e0550240741fc41f3fc002b382eed8730e33c5d8de40256e4accee846667f536832f711ab1d4590e7db91a8a116ac5bff3be13d3f9243ff2e976662aa9b395d907f8e9c9024046a5696c9ef882363e06c9fa4e2f5b580906452befba03f4a99d0f873697ef1f851d2226ca7934b30b7c3e80cb634a67172bbbf4781735fe3e09263e2dd723e7"

+ 748
- 0
vendor/src/golang.org/x/crypto/openpgp/packet/public_key.go 查看文件

@@ -0,0 +1,748 @@
1
+// Copyright 2011 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
+
5
+package packet
6
+
7
+import (
8
+	"bytes"
9
+	"crypto"
10
+	"crypto/dsa"
11
+	"crypto/ecdsa"
12
+	"crypto/elliptic"
13
+	"crypto/rsa"
14
+	"crypto/sha1"
15
+	_ "crypto/sha256"
16
+	_ "crypto/sha512"
17
+	"encoding/binary"
18
+	"fmt"
19
+	"hash"
20
+	"io"
21
+	"math/big"
22
+	"strconv"
23
+	"time"
24
+
25
+	"golang.org/x/crypto/openpgp/elgamal"
26
+	"golang.org/x/crypto/openpgp/errors"
27
+)
28
+
29
+var (
30
+	// NIST curve P-256
31
+	oidCurveP256 []byte = []byte{0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07}
32
+	// NIST curve P-384
33
+	oidCurveP384 []byte = []byte{0x2B, 0x81, 0x04, 0x00, 0x22}
34
+	// NIST curve P-521
35
+	oidCurveP521 []byte = []byte{0x2B, 0x81, 0x04, 0x00, 0x23}
36
+)
37
+
38
+const maxOIDLength = 8
39
+
40
+// ecdsaKey stores the algorithm-specific fields for ECDSA keys.
41
+// as defined in RFC 6637, Section 9.
42
+type ecdsaKey struct {
43
+	// oid contains the OID byte sequence identifying the elliptic curve used
44
+	oid []byte
45
+	// p contains the elliptic curve point that represents the public key
46
+	p parsedMPI
47
+}
48
+
49
+// parseOID reads the OID for the curve as defined in RFC 6637, Section 9.
50
+func parseOID(r io.Reader) (oid []byte, err error) {
51
+	buf := make([]byte, maxOIDLength)
52
+	if _, err = readFull(r, buf[:1]); err != nil {
53
+		return
54
+	}
55
+	oidLen := buf[0]
56
+	if int(oidLen) > len(buf) {
57
+		err = errors.UnsupportedError("invalid oid length: " + strconv.Itoa(int(oidLen)))
58
+		return
59
+	}
60
+	oid = buf[:oidLen]
61
+	_, err = readFull(r, oid)
62
+	return
63
+}
64
+
65
+func (f *ecdsaKey) parse(r io.Reader) (err error) {
66
+	if f.oid, err = parseOID(r); err != nil {
67
+		return err
68
+	}
69
+	f.p.bytes, f.p.bitLength, err = readMPI(r)
70
+	return
71
+}
72
+
73
+func (f *ecdsaKey) serialize(w io.Writer) (err error) {
74
+	buf := make([]byte, maxOIDLength+1)
75
+	buf[0] = byte(len(f.oid))
76
+	copy(buf[1:], f.oid)
77
+	if _, err = w.Write(buf[:len(f.oid)+1]); err != nil {
78
+		return
79
+	}
80
+	return writeMPIs(w, f.p)
81
+}
82
+
83
+func (f *ecdsaKey) newECDSA() (*ecdsa.PublicKey, error) {
84
+	var c elliptic.Curve
85
+	if bytes.Equal(f.oid, oidCurveP256) {
86
+		c = elliptic.P256()
87
+	} else if bytes.Equal(f.oid, oidCurveP384) {
88
+		c = elliptic.P384()
89
+	} else if bytes.Equal(f.oid, oidCurveP521) {
90
+		c = elliptic.P521()
91
+	} else {
92
+		return nil, errors.UnsupportedError(fmt.Sprintf("unsupported oid: %x", f.oid))
93
+	}
94
+	x, y := elliptic.Unmarshal(c, f.p.bytes)
95
+	if x == nil {
96
+		return nil, errors.UnsupportedError("failed to parse EC point")
97
+	}
98
+	return &ecdsa.PublicKey{Curve: c, X: x, Y: y}, nil
99
+}
100
+
101
+func (f *ecdsaKey) byteLen() int {
102
+	return 1 + len(f.oid) + 2 + len(f.p.bytes)
103
+}
104
+
105
+type kdfHashFunction byte
106
+type kdfAlgorithm byte
107
+
108
+// ecdhKdf stores key derivation function parameters
109
+// used for ECDH encryption. See RFC 6637, Section 9.
110
+type ecdhKdf struct {
111
+	KdfHash kdfHashFunction
112
+	KdfAlgo kdfAlgorithm
113
+}
114
+
115
+func (f *ecdhKdf) parse(r io.Reader) (err error) {
116
+	buf := make([]byte, 1)
117
+	if _, err = readFull(r, buf); err != nil {
118
+		return
119
+	}
120
+	kdfLen := int(buf[0])
121
+	if kdfLen < 3 {
122
+		return errors.UnsupportedError("Unsupported ECDH KDF length: " + strconv.Itoa(kdfLen))
123
+	}
124
+	buf = make([]byte, kdfLen)
125
+	if _, err = readFull(r, buf); err != nil {
126
+		return
127
+	}
128
+	reserved := int(buf[0])
129
+	f.KdfHash = kdfHashFunction(buf[1])
130
+	f.KdfAlgo = kdfAlgorithm(buf[2])
131
+	if reserved != 0x01 {
132
+		return errors.UnsupportedError("Unsupported KDF reserved field: " + strconv.Itoa(reserved))
133
+	}
134
+	return
135
+}
136
+
137
+func (f *ecdhKdf) serialize(w io.Writer) (err error) {
138
+	buf := make([]byte, 4)
139
+	// See RFC 6637, Section 9, Algorithm-Specific Fields for ECDH keys.
140
+	buf[0] = byte(0x03) // Length of the following fields
141
+	buf[1] = byte(0x01) // Reserved for future extensions, must be 1 for now
142
+	buf[2] = byte(f.KdfHash)
143
+	buf[3] = byte(f.KdfAlgo)
144
+	_, err = w.Write(buf[:])
145
+	return
146
+}
147
+
148
+func (f *ecdhKdf) byteLen() int {
149
+	return 4
150
+}
151
+
152
+// PublicKey represents an OpenPGP public key. See RFC 4880, section 5.5.2.
153
+type PublicKey struct {
154
+	CreationTime time.Time
155
+	PubKeyAlgo   PublicKeyAlgorithm
156
+	PublicKey    interface{} // *rsa.PublicKey, *dsa.PublicKey or *ecdsa.PublicKey
157
+	Fingerprint  [20]byte
158
+	KeyId        uint64
159
+	IsSubkey     bool
160
+
161
+	n, e, p, q, g, y parsedMPI
162
+
163
+	// RFC 6637 fields
164
+	ec   *ecdsaKey
165
+	ecdh *ecdhKdf
166
+}
167
+
168
+// signingKey provides a convenient abstraction over signature verification
169
+// for v3 and v4 public keys.
170
+type signingKey interface {
171
+	SerializeSignaturePrefix(io.Writer)
172
+	serializeWithoutHeaders(io.Writer) error
173
+}
174
+
175
+func fromBig(n *big.Int) parsedMPI {
176
+	return parsedMPI{
177
+		bytes:     n.Bytes(),
178
+		bitLength: uint16(n.BitLen()),
179
+	}
180
+}
181
+
182
+// NewRSAPublicKey returns a PublicKey that wraps the given rsa.PublicKey.
183
+func NewRSAPublicKey(creationTime time.Time, pub *rsa.PublicKey) *PublicKey {
184
+	pk := &PublicKey{
185
+		CreationTime: creationTime,
186
+		PubKeyAlgo:   PubKeyAlgoRSA,
187
+		PublicKey:    pub,
188
+		n:            fromBig(pub.N),
189
+		e:            fromBig(big.NewInt(int64(pub.E))),
190
+	}
191
+
192
+	pk.setFingerPrintAndKeyId()
193
+	return pk
194
+}
195
+
196
+// NewDSAPublicKey returns a PublicKey that wraps the given dsa.PublicKey.
197
+func NewDSAPublicKey(creationTime time.Time, pub *dsa.PublicKey) *PublicKey {
198
+	pk := &PublicKey{
199
+		CreationTime: creationTime,
200
+		PubKeyAlgo:   PubKeyAlgoDSA,
201
+		PublicKey:    pub,
202
+		p:            fromBig(pub.P),
203
+		q:            fromBig(pub.Q),
204
+		g:            fromBig(pub.G),
205
+		y:            fromBig(pub.Y),
206
+	}
207
+
208
+	pk.setFingerPrintAndKeyId()
209
+	return pk
210
+}
211
+
212
+// NewElGamalPublicKey returns a PublicKey that wraps the given elgamal.PublicKey.
213
+func NewElGamalPublicKey(creationTime time.Time, pub *elgamal.PublicKey) *PublicKey {
214
+	pk := &PublicKey{
215
+		CreationTime: creationTime,
216
+		PubKeyAlgo:   PubKeyAlgoElGamal,
217
+		PublicKey:    pub,
218
+		p:            fromBig(pub.P),
219
+		g:            fromBig(pub.G),
220
+		y:            fromBig(pub.Y),
221
+	}
222
+
223
+	pk.setFingerPrintAndKeyId()
224
+	return pk
225
+}
226
+
227
+func NewECDSAPublicKey(creationTime time.Time, pub *ecdsa.PublicKey) *PublicKey {
228
+	pk := &PublicKey{
229
+		CreationTime: creationTime,
230
+		PubKeyAlgo:   PubKeyAlgoECDSA,
231
+		PublicKey:    pub,
232
+		ec:           new(ecdsaKey),
233
+	}
234
+
235
+	switch pub.Curve {
236
+	case elliptic.P256():
237
+		pk.ec.oid = oidCurveP256
238
+	case elliptic.P384():
239
+		pk.ec.oid = oidCurveP384
240
+	case elliptic.P521():
241
+		pk.ec.oid = oidCurveP521
242
+	default:
243
+		panic("unknown elliptic curve")
244
+	}
245
+
246
+	pk.ec.p.bytes = elliptic.Marshal(pub.Curve, pub.X, pub.Y)
247
+	pk.ec.p.bitLength = uint16(8 * len(pk.ec.p.bytes))
248
+
249
+	pk.setFingerPrintAndKeyId()
250
+	return pk
251
+}
252
+
253
+func (pk *PublicKey) parse(r io.Reader) (err error) {
254
+	// RFC 4880, section 5.5.2
255
+	var buf [6]byte
256
+	_, err = readFull(r, buf[:])
257
+	if err != nil {
258
+		return
259
+	}
260
+	if buf[0] != 4 {
261
+		return errors.UnsupportedError("public key version")
262
+	}
263
+	pk.CreationTime = time.Unix(int64(uint32(buf[1])<<24|uint32(buf[2])<<16|uint32(buf[3])<<8|uint32(buf[4])), 0)
264
+	pk.PubKeyAlgo = PublicKeyAlgorithm(buf[5])
265
+	switch pk.PubKeyAlgo {
266
+	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
267
+		err = pk.parseRSA(r)
268
+	case PubKeyAlgoDSA:
269
+		err = pk.parseDSA(r)
270
+	case PubKeyAlgoElGamal:
271
+		err = pk.parseElGamal(r)
272
+	case PubKeyAlgoECDSA:
273
+		pk.ec = new(ecdsaKey)
274
+		if err = pk.ec.parse(r); err != nil {
275
+			return err
276
+		}
277
+		pk.PublicKey, err = pk.ec.newECDSA()
278
+	case PubKeyAlgoECDH:
279
+		pk.ec = new(ecdsaKey)
280
+		if err = pk.ec.parse(r); err != nil {
281
+			return
282
+		}
283
+		pk.ecdh = new(ecdhKdf)
284
+		if err = pk.ecdh.parse(r); err != nil {
285
+			return
286
+		}
287
+		// The ECDH key is stored in an ecdsa.PublicKey for convenience.
288
+		pk.PublicKey, err = pk.ec.newECDSA()
289
+	default:
290
+		err = errors.UnsupportedError("public key type: " + strconv.Itoa(int(pk.PubKeyAlgo)))
291
+	}
292
+	if err != nil {
293
+		return
294
+	}
295
+
296
+	pk.setFingerPrintAndKeyId()
297
+	return
298
+}
299
+
300
+func (pk *PublicKey) setFingerPrintAndKeyId() {
301
+	// RFC 4880, section 12.2
302
+	fingerPrint := sha1.New()
303
+	pk.SerializeSignaturePrefix(fingerPrint)
304
+	pk.serializeWithoutHeaders(fingerPrint)
305
+	copy(pk.Fingerprint[:], fingerPrint.Sum(nil))
306
+	pk.KeyId = binary.BigEndian.Uint64(pk.Fingerprint[12:20])
307
+}
308
+
309
+// parseRSA parses RSA public key material from the given Reader. See RFC 4880,
310
+// section 5.5.2.
311
+func (pk *PublicKey) parseRSA(r io.Reader) (err error) {
312
+	pk.n.bytes, pk.n.bitLength, err = readMPI(r)
313
+	if err != nil {
314
+		return
315
+	}
316
+	pk.e.bytes, pk.e.bitLength, err = readMPI(r)
317
+	if err != nil {
318
+		return
319
+	}
320
+
321
+	if len(pk.e.bytes) > 3 {
322
+		err = errors.UnsupportedError("large public exponent")
323
+		return
324
+	}
325
+	rsa := &rsa.PublicKey{
326
+		N: new(big.Int).SetBytes(pk.n.bytes),
327
+		E: 0,
328
+	}
329
+	for i := 0; i < len(pk.e.bytes); i++ {
330
+		rsa.E <<= 8
331
+		rsa.E |= int(pk.e.bytes[i])
332
+	}
333
+	pk.PublicKey = rsa
334
+	return
335
+}
336
+
337
+// parseDSA parses DSA public key material from the given Reader. See RFC 4880,
338
+// section 5.5.2.
339
+func (pk *PublicKey) parseDSA(r io.Reader) (err error) {
340
+	pk.p.bytes, pk.p.bitLength, err = readMPI(r)
341
+	if err != nil {
342
+		return
343
+	}
344
+	pk.q.bytes, pk.q.bitLength, err = readMPI(r)
345
+	if err != nil {
346
+		return
347
+	}
348
+	pk.g.bytes, pk.g.bitLength, err = readMPI(r)
349
+	if err != nil {
350
+		return
351
+	}
352
+	pk.y.bytes, pk.y.bitLength, err = readMPI(r)
353
+	if err != nil {
354
+		return
355
+	}
356
+
357
+	dsa := new(dsa.PublicKey)
358
+	dsa.P = new(big.Int).SetBytes(pk.p.bytes)
359
+	dsa.Q = new(big.Int).SetBytes(pk.q.bytes)
360
+	dsa.G = new(big.Int).SetBytes(pk.g.bytes)
361
+	dsa.Y = new(big.Int).SetBytes(pk.y.bytes)
362
+	pk.PublicKey = dsa
363
+	return
364
+}
365
+
366
+// parseElGamal parses ElGamal public key material from the given Reader. See
367
+// RFC 4880, section 5.5.2.
368
+func (pk *PublicKey) parseElGamal(r io.Reader) (err error) {
369
+	pk.p.bytes, pk.p.bitLength, err = readMPI(r)
370
+	if err != nil {
371
+		return
372
+	}
373
+	pk.g.bytes, pk.g.bitLength, err = readMPI(r)
374
+	if err != nil {
375
+		return
376
+	}
377
+	pk.y.bytes, pk.y.bitLength, err = readMPI(r)
378
+	if err != nil {
379
+		return
380
+	}
381
+
382
+	elgamal := new(elgamal.PublicKey)
383
+	elgamal.P = new(big.Int).SetBytes(pk.p.bytes)
384
+	elgamal.G = new(big.Int).SetBytes(pk.g.bytes)
385
+	elgamal.Y = new(big.Int).SetBytes(pk.y.bytes)
386
+	pk.PublicKey = elgamal
387
+	return
388
+}
389
+
390
+// SerializeSignaturePrefix writes the prefix for this public key to the given Writer.
391
+// The prefix is used when calculating a signature over this public key. See
392
+// RFC 4880, section 5.2.4.
393
+func (pk *PublicKey) SerializeSignaturePrefix(h io.Writer) {
394
+	var pLength uint16
395
+	switch pk.PubKeyAlgo {
396
+	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
397
+		pLength += 2 + uint16(len(pk.n.bytes))
398
+		pLength += 2 + uint16(len(pk.e.bytes))
399
+	case PubKeyAlgoDSA:
400
+		pLength += 2 + uint16(len(pk.p.bytes))
401
+		pLength += 2 + uint16(len(pk.q.bytes))
402
+		pLength += 2 + uint16(len(pk.g.bytes))
403
+		pLength += 2 + uint16(len(pk.y.bytes))
404
+	case PubKeyAlgoElGamal:
405
+		pLength += 2 + uint16(len(pk.p.bytes))
406
+		pLength += 2 + uint16(len(pk.g.bytes))
407
+		pLength += 2 + uint16(len(pk.y.bytes))
408
+	case PubKeyAlgoECDSA:
409
+		pLength += uint16(pk.ec.byteLen())
410
+	case PubKeyAlgoECDH:
411
+		pLength += uint16(pk.ec.byteLen())
412
+		pLength += uint16(pk.ecdh.byteLen())
413
+	default:
414
+		panic("unknown public key algorithm")
415
+	}
416
+	pLength += 6
417
+	h.Write([]byte{0x99, byte(pLength >> 8), byte(pLength)})
418
+	return
419
+}
420
+
421
+func (pk *PublicKey) Serialize(w io.Writer) (err error) {
422
+	length := 6 // 6 byte header
423
+
424
+	switch pk.PubKeyAlgo {
425
+	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
426
+		length += 2 + len(pk.n.bytes)
427
+		length += 2 + len(pk.e.bytes)
428
+	case PubKeyAlgoDSA:
429
+		length += 2 + len(pk.p.bytes)
430
+		length += 2 + len(pk.q.bytes)
431
+		length += 2 + len(pk.g.bytes)
432
+		length += 2 + len(pk.y.bytes)
433
+	case PubKeyAlgoElGamal:
434
+		length += 2 + len(pk.p.bytes)
435
+		length += 2 + len(pk.g.bytes)
436
+		length += 2 + len(pk.y.bytes)
437
+	case PubKeyAlgoECDSA:
438
+		length += pk.ec.byteLen()
439
+	case PubKeyAlgoECDH:
440
+		length += pk.ec.byteLen()
441
+		length += pk.ecdh.byteLen()
442
+	default:
443
+		panic("unknown public key algorithm")
444
+	}
445
+
446
+	packetType := packetTypePublicKey
447
+	if pk.IsSubkey {
448
+		packetType = packetTypePublicSubkey
449
+	}
450
+	err = serializeHeader(w, packetType, length)
451
+	if err != nil {
452
+		return
453
+	}
454
+	return pk.serializeWithoutHeaders(w)
455
+}
456
+
457
+// serializeWithoutHeaders marshals the PublicKey to w in the form of an
458
+// OpenPGP public key packet, not including the packet header.
459
+func (pk *PublicKey) serializeWithoutHeaders(w io.Writer) (err error) {
460
+	var buf [6]byte
461
+	buf[0] = 4
462
+	t := uint32(pk.CreationTime.Unix())
463
+	buf[1] = byte(t >> 24)
464
+	buf[2] = byte(t >> 16)
465
+	buf[3] = byte(t >> 8)
466
+	buf[4] = byte(t)
467
+	buf[5] = byte(pk.PubKeyAlgo)
468
+
469
+	_, err = w.Write(buf[:])
470
+	if err != nil {
471
+		return
472
+	}
473
+
474
+	switch pk.PubKeyAlgo {
475
+	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
476
+		return writeMPIs(w, pk.n, pk.e)
477
+	case PubKeyAlgoDSA:
478
+		return writeMPIs(w, pk.p, pk.q, pk.g, pk.y)
479
+	case PubKeyAlgoElGamal:
480
+		return writeMPIs(w, pk.p, pk.g, pk.y)
481
+	case PubKeyAlgoECDSA:
482
+		return pk.ec.serialize(w)
483
+	case PubKeyAlgoECDH:
484
+		if err = pk.ec.serialize(w); err != nil {
485
+			return
486
+		}
487
+		return pk.ecdh.serialize(w)
488
+	}
489
+	return errors.InvalidArgumentError("bad public-key algorithm")
490
+}
491
+
492
+// CanSign returns true iff this public key can generate signatures
493
+func (pk *PublicKey) CanSign() bool {
494
+	return pk.PubKeyAlgo != PubKeyAlgoRSAEncryptOnly && pk.PubKeyAlgo != PubKeyAlgoElGamal
495
+}
496
+
497
+// VerifySignature returns nil iff sig is a valid signature, made by this
498
+// public key, of the data hashed into signed. signed is mutated by this call.
499
+func (pk *PublicKey) VerifySignature(signed hash.Hash, sig *Signature) (err error) {
500
+	if !pk.CanSign() {
501
+		return errors.InvalidArgumentError("public key cannot generate signatures")
502
+	}
503
+
504
+	signed.Write(sig.HashSuffix)
505
+	hashBytes := signed.Sum(nil)
506
+
507
+	if hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1] {
508
+		return errors.SignatureError("hash tag doesn't match")
509
+	}
510
+
511
+	if pk.PubKeyAlgo != sig.PubKeyAlgo {
512
+		return errors.InvalidArgumentError("public key and signature use different algorithms")
513
+	}
514
+
515
+	switch pk.PubKeyAlgo {
516
+	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
517
+		rsaPublicKey, _ := pk.PublicKey.(*rsa.PublicKey)
518
+		err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, sig.RSASignature.bytes)
519
+		if err != nil {
520
+			return errors.SignatureError("RSA verification failure")
521
+		}
522
+		return nil
523
+	case PubKeyAlgoDSA:
524
+		dsaPublicKey, _ := pk.PublicKey.(*dsa.PublicKey)
525
+		// Need to truncate hashBytes to match FIPS 186-3 section 4.6.
526
+		subgroupSize := (dsaPublicKey.Q.BitLen() + 7) / 8
527
+		if len(hashBytes) > subgroupSize {
528
+			hashBytes = hashBytes[:subgroupSize]
529
+		}
530
+		if !dsa.Verify(dsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.DSASigR.bytes), new(big.Int).SetBytes(sig.DSASigS.bytes)) {
531
+			return errors.SignatureError("DSA verification failure")
532
+		}
533
+		return nil
534
+	case PubKeyAlgoECDSA:
535
+		ecdsaPublicKey := pk.PublicKey.(*ecdsa.PublicKey)
536
+		if !ecdsa.Verify(ecdsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.ECDSASigR.bytes), new(big.Int).SetBytes(sig.ECDSASigS.bytes)) {
537
+			return errors.SignatureError("ECDSA verification failure")
538
+		}
539
+		return nil
540
+	default:
541
+		return errors.SignatureError("Unsupported public key algorithm used in signature")
542
+	}
543
+}
544
+
545
+// VerifySignatureV3 returns nil iff sig is a valid signature, made by this
546
+// public key, of the data hashed into signed. signed is mutated by this call.
547
+func (pk *PublicKey) VerifySignatureV3(signed hash.Hash, sig *SignatureV3) (err error) {
548
+	if !pk.CanSign() {
549
+		return errors.InvalidArgumentError("public key cannot generate signatures")
550
+	}
551
+
552
+	suffix := make([]byte, 5)
553
+	suffix[0] = byte(sig.SigType)
554
+	binary.BigEndian.PutUint32(suffix[1:], uint32(sig.CreationTime.Unix()))
555
+	signed.Write(suffix)
556
+	hashBytes := signed.Sum(nil)
557
+
558
+	if hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1] {
559
+		return errors.SignatureError("hash tag doesn't match")
560
+	}
561
+
562
+	if pk.PubKeyAlgo != sig.PubKeyAlgo {
563
+		return errors.InvalidArgumentError("public key and signature use different algorithms")
564
+	}
565
+
566
+	switch pk.PubKeyAlgo {
567
+	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
568
+		rsaPublicKey := pk.PublicKey.(*rsa.PublicKey)
569
+		if err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, sig.RSASignature.bytes); err != nil {
570
+			return errors.SignatureError("RSA verification failure")
571
+		}
572
+		return
573
+	case PubKeyAlgoDSA:
574
+		dsaPublicKey := pk.PublicKey.(*dsa.PublicKey)
575
+		// Need to truncate hashBytes to match FIPS 186-3 section 4.6.
576
+		subgroupSize := (dsaPublicKey.Q.BitLen() + 7) / 8
577
+		if len(hashBytes) > subgroupSize {
578
+			hashBytes = hashBytes[:subgroupSize]
579
+		}
580
+		if !dsa.Verify(dsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.DSASigR.bytes), new(big.Int).SetBytes(sig.DSASigS.bytes)) {
581
+			return errors.SignatureError("DSA verification failure")
582
+		}
583
+		return nil
584
+	default:
585
+		panic("shouldn't happen")
586
+	}
587
+}
588
+
589
+// keySignatureHash returns a Hash of the message that needs to be signed for
590
+// pk to assert a subkey relationship to signed.
591
+func keySignatureHash(pk, signed signingKey, hashFunc crypto.Hash) (h hash.Hash, err error) {
592
+	if !hashFunc.Available() {
593
+		return nil, errors.UnsupportedError("hash function")
594
+	}
595
+	h = hashFunc.New()
596
+
597
+	// RFC 4880, section 5.2.4
598
+	pk.SerializeSignaturePrefix(h)
599
+	pk.serializeWithoutHeaders(h)
600
+	signed.SerializeSignaturePrefix(h)
601
+	signed.serializeWithoutHeaders(h)
602
+	return
603
+}
604
+
605
+// VerifyKeySignature returns nil iff sig is a valid signature, made by this
606
+// public key, of signed.
607
+func (pk *PublicKey) VerifyKeySignature(signed *PublicKey, sig *Signature) error {
608
+	h, err := keySignatureHash(pk, signed, sig.Hash)
609
+	if err != nil {
610
+		return err
611
+	}
612
+	if err = pk.VerifySignature(h, sig); err != nil {
613
+		return err
614
+	}
615
+
616
+	if sig.FlagSign {
617
+		// Signing subkeys must be cross-signed. See
618
+		// https://www.gnupg.org/faq/subkey-cross-certify.html.
619
+		if sig.EmbeddedSignature == nil {
620
+			return errors.StructuralError("signing subkey is missing cross-signature")
621
+		}
622
+		// Verify the cross-signature. This is calculated over the same
623
+		// data as the main signature, so we cannot just recursively
624
+		// call signed.VerifyKeySignature(...)
625
+		if h, err = keySignatureHash(pk, signed, sig.EmbeddedSignature.Hash); err != nil {
626
+			return errors.StructuralError("error while hashing for cross-signature: " + err.Error())
627
+		}
628
+		if err := signed.VerifySignature(h, sig.EmbeddedSignature); err != nil {
629
+			return errors.StructuralError("error while verifying cross-signature: " + err.Error())
630
+		}
631
+	}
632
+
633
+	return nil
634
+}
635
+
636
+func keyRevocationHash(pk signingKey, hashFunc crypto.Hash) (h hash.Hash, err error) {
637
+	if !hashFunc.Available() {
638
+		return nil, errors.UnsupportedError("hash function")
639
+	}
640
+	h = hashFunc.New()
641
+
642
+	// RFC 4880, section 5.2.4
643
+	pk.SerializeSignaturePrefix(h)
644
+	pk.serializeWithoutHeaders(h)
645
+
646
+	return
647
+}
648
+
649
+// VerifyRevocationSignature returns nil iff sig is a valid signature, made by this
650
+// public key.
651
+func (pk *PublicKey) VerifyRevocationSignature(sig *Signature) (err error) {
652
+	h, err := keyRevocationHash(pk, sig.Hash)
653
+	if err != nil {
654
+		return err
655
+	}
656
+	return pk.VerifySignature(h, sig)
657
+}
658
+
659
+// userIdSignatureHash returns a Hash of the message that needs to be signed
660
+// to assert that pk is a valid key for id.
661
+func userIdSignatureHash(id string, pk *PublicKey, hashFunc crypto.Hash) (h hash.Hash, err error) {
662
+	if !hashFunc.Available() {
663
+		return nil, errors.UnsupportedError("hash function")
664
+	}
665
+	h = hashFunc.New()
666
+
667
+	// RFC 4880, section 5.2.4
668
+	pk.SerializeSignaturePrefix(h)
669
+	pk.serializeWithoutHeaders(h)
670
+
671
+	var buf [5]byte
672
+	buf[0] = 0xb4
673
+	buf[1] = byte(len(id) >> 24)
674
+	buf[2] = byte(len(id) >> 16)
675
+	buf[3] = byte(len(id) >> 8)
676
+	buf[4] = byte(len(id))
677
+	h.Write(buf[:])
678
+	h.Write([]byte(id))
679
+
680
+	return
681
+}
682
+
683
+// VerifyUserIdSignature returns nil iff sig is a valid signature, made by this
684
+// public key, that id is the identity of pub.
685
+func (pk *PublicKey) VerifyUserIdSignature(id string, pub *PublicKey, sig *Signature) (err error) {
686
+	h, err := userIdSignatureHash(id, pub, sig.Hash)
687
+	if err != nil {
688
+		return err
689
+	}
690
+	return pk.VerifySignature(h, sig)
691
+}
692
+
693
+// VerifyUserIdSignatureV3 returns nil iff sig is a valid signature, made by this
694
+// public key, that id is the identity of pub.
695
+func (pk *PublicKey) VerifyUserIdSignatureV3(id string, pub *PublicKey, sig *SignatureV3) (err error) {
696
+	h, err := userIdSignatureV3Hash(id, pub, sig.Hash)
697
+	if err != nil {
698
+		return err
699
+	}
700
+	return pk.VerifySignatureV3(h, sig)
701
+}
702
+
703
+// KeyIdString returns the public key's fingerprint in capital hex
704
+// (e.g. "6C7EE1B8621CC013").
705
+func (pk *PublicKey) KeyIdString() string {
706
+	return fmt.Sprintf("%X", pk.Fingerprint[12:20])
707
+}
708
+
709
+// KeyIdShortString returns the short form of public key's fingerprint
710
+// in capital hex, as shown by gpg --list-keys (e.g. "621CC013").
711
+func (pk *PublicKey) KeyIdShortString() string {
712
+	return fmt.Sprintf("%X", pk.Fingerprint[16:20])
713
+}
714
+
715
+// A parsedMPI is used to store the contents of a big integer, along with the
716
+// bit length that was specified in the original input. This allows the MPI to
717
+// be reserialized exactly.
718
+type parsedMPI struct {
719
+	bytes     []byte
720
+	bitLength uint16
721
+}
722
+
723
+// writeMPIs is a utility function for serializing several big integers to the
724
+// given Writer.
725
+func writeMPIs(w io.Writer, mpis ...parsedMPI) (err error) {
726
+	for _, mpi := range mpis {
727
+		err = writeMPI(w, mpi.bitLength, mpi.bytes)
728
+		if err != nil {
729
+			return
730
+		}
731
+	}
732
+	return
733
+}
734
+
735
+// BitLength returns the bit length for the given public key.
736
+func (pk *PublicKey) BitLength() (bitLength uint16, err error) {
737
+	switch pk.PubKeyAlgo {
738
+	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
739
+		bitLength = pk.n.bitLength
740
+	case PubKeyAlgoDSA:
741
+		bitLength = pk.p.bitLength
742
+	case PubKeyAlgoElGamal:
743
+		bitLength = pk.p.bitLength
744
+	default:
745
+		err = errors.InvalidArgumentError("bad public-key algorithm")
746
+	}
747
+	return
748
+}

+ 202
- 0
vendor/src/golang.org/x/crypto/openpgp/packet/public_key_test.go 查看文件

@@ -0,0 +1,202 @@
1
+// Copyright 2011 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
+
5
+package packet
6
+
7
+import (
8
+	"bytes"
9
+	"encoding/hex"
10
+	"testing"
11
+	"time"
12
+)
13
+
14
+var pubKeyTests = []struct {
15
+	hexData        string
16
+	hexFingerprint string
17
+	creationTime   time.Time
18
+	pubKeyAlgo     PublicKeyAlgorithm
19
+	keyId          uint64
20
+	keyIdString    string
21
+	keyIdShort     string
22
+}{
23
+	{rsaPkDataHex, rsaFingerprintHex, time.Unix(0x4d3c5c10, 0), PubKeyAlgoRSA, 0xa34d7e18c20c31bb, "A34D7E18C20C31BB", "C20C31BB"},
24
+	{dsaPkDataHex, dsaFingerprintHex, time.Unix(0x4d432f89, 0), PubKeyAlgoDSA, 0x8e8fbe54062f19ed, "8E8FBE54062F19ED", "062F19ED"},
25
+	{ecdsaPkDataHex, ecdsaFingerprintHex, time.Unix(0x5071c294, 0), PubKeyAlgoECDSA, 0x43fe956c542ca00b, "43FE956C542CA00B", "542CA00B"},
26
+}
27
+
28
+func TestPublicKeyRead(t *testing.T) {
29
+	for i, test := range pubKeyTests {
30
+		packet, err := Read(readerFromHex(test.hexData))
31
+		if err != nil {
32
+			t.Errorf("#%d: Read error: %s", i, err)
33
+			continue
34
+		}
35
+		pk, ok := packet.(*PublicKey)
36
+		if !ok {
37
+			t.Errorf("#%d: failed to parse, got: %#v", i, packet)
38
+			continue
39
+		}
40
+		if pk.PubKeyAlgo != test.pubKeyAlgo {
41
+			t.Errorf("#%d: bad public key algorithm got:%x want:%x", i, pk.PubKeyAlgo, test.pubKeyAlgo)
42
+		}
43
+		if !pk.CreationTime.Equal(test.creationTime) {
44
+			t.Errorf("#%d: bad creation time got:%v want:%v", i, pk.CreationTime, test.creationTime)
45
+		}
46
+		expectedFingerprint, _ := hex.DecodeString(test.hexFingerprint)
47
+		if !bytes.Equal(expectedFingerprint, pk.Fingerprint[:]) {
48
+			t.Errorf("#%d: bad fingerprint got:%x want:%x", i, pk.Fingerprint[:], expectedFingerprint)
49
+		}
50
+		if pk.KeyId != test.keyId {
51
+			t.Errorf("#%d: bad keyid got:%x want:%x", i, pk.KeyId, test.keyId)
52
+		}
53
+		if g, e := pk.KeyIdString(), test.keyIdString; g != e {
54
+			t.Errorf("#%d: bad KeyIdString got:%q want:%q", i, g, e)
55
+		}
56
+		if g, e := pk.KeyIdShortString(), test.keyIdShort; g != e {
57
+			t.Errorf("#%d: bad KeyIdShortString got:%q want:%q", i, g, e)
58
+		}
59
+	}
60
+}
61
+
62
+func TestPublicKeySerialize(t *testing.T) {
63
+	for i, test := range pubKeyTests {
64
+		packet, err := Read(readerFromHex(test.hexData))
65
+		if err != nil {
66
+			t.Errorf("#%d: Read error: %s", i, err)
67
+			continue
68
+		}
69
+		pk, ok := packet.(*PublicKey)
70
+		if !ok {
71
+			t.Errorf("#%d: failed to parse, got: %#v", i, packet)
72
+			continue
73
+		}
74
+		serializeBuf := bytes.NewBuffer(nil)
75
+		err = pk.Serialize(serializeBuf)
76
+		if err != nil {
77
+			t.Errorf("#%d: failed to serialize: %s", i, err)
78
+			continue
79
+		}
80
+
81
+		packet, err = Read(serializeBuf)
82
+		if err != nil {
83
+			t.Errorf("#%d: Read error (from serialized data): %s", i, err)
84
+			continue
85
+		}
86
+		pk, ok = packet.(*PublicKey)
87
+		if !ok {
88
+			t.Errorf("#%d: failed to parse serialized data, got: %#v", i, packet)
89
+			continue
90
+		}
91
+	}
92
+}
93
+
94
+func TestEcc384Serialize(t *testing.T) {
95
+	r := readerFromHex(ecc384PubHex)
96
+	var w bytes.Buffer
97
+	for i := 0; i < 2; i++ {
98
+		// Public key
99
+		p, err := Read(r)
100
+		if err != nil {
101
+			t.Error(err)
102
+		}
103
+		pubkey := p.(*PublicKey)
104
+		if !bytes.Equal(pubkey.ec.oid, []byte{0x2b, 0x81, 0x04, 0x00, 0x22}) {
105
+			t.Errorf("Unexpected pubkey OID: %x", pubkey.ec.oid)
106
+		}
107
+		if !bytes.Equal(pubkey.ec.p.bytes[:5], []byte{0x04, 0xf6, 0xb8, 0xc5, 0xac}) {
108
+			t.Errorf("Unexpected pubkey P[:5]: %x", pubkey.ec.p.bytes)
109
+		}
110
+		if pubkey.KeyId != 0x098033880F54719F {
111
+			t.Errorf("Unexpected pubkey ID: %x", pubkey.KeyId)
112
+		}
113
+		err = pubkey.Serialize(&w)
114
+		if err != nil {
115
+			t.Error(err)
116
+		}
117
+		// User ID
118
+		p, err = Read(r)
119
+		if err != nil {
120
+			t.Error(err)
121
+		}
122
+		uid := p.(*UserId)
123
+		if uid.Id != "ec_dsa_dh_384 <openpgp@brainhub.org>" {
124
+			t.Error("Unexpected UID:", uid.Id)
125
+		}
126
+		err = uid.Serialize(&w)
127
+		if err != nil {
128
+			t.Error(err)
129
+		}
130
+		// User ID Sig
131
+		p, err = Read(r)
132
+		if err != nil {
133
+			t.Error(err)
134
+		}
135
+		uidSig := p.(*Signature)
136
+		err = pubkey.VerifyUserIdSignature(uid.Id, pubkey, uidSig)
137
+		if err != nil {
138
+			t.Error(err, ": UID")
139
+		}
140
+		err = uidSig.Serialize(&w)
141
+		if err != nil {
142
+			t.Error(err)
143
+		}
144
+		// Subkey
145
+		p, err = Read(r)
146
+		if err != nil {
147
+			t.Error(err)
148
+		}
149
+		subkey := p.(*PublicKey)
150
+		if !bytes.Equal(subkey.ec.oid, []byte{0x2b, 0x81, 0x04, 0x00, 0x22}) {
151
+			t.Errorf("Unexpected subkey OID: %x", subkey.ec.oid)
152
+		}
153
+		if !bytes.Equal(subkey.ec.p.bytes[:5], []byte{0x04, 0x2f, 0xaa, 0x84, 0x02}) {
154
+			t.Errorf("Unexpected subkey P[:5]: %x", subkey.ec.p.bytes)
155
+		}
156
+		if subkey.ecdh.KdfHash != 0x09 {
157
+			t.Error("Expected KDF hash function SHA384 (0x09), got", subkey.ecdh.KdfHash)
158
+		}
159
+		if subkey.ecdh.KdfAlgo != 0x09 {
160
+			t.Error("Expected KDF symmetric alg AES256 (0x09), got", subkey.ecdh.KdfAlgo)
161
+		}
162
+		if subkey.KeyId != 0xAA8B938F9A201946 {
163
+			t.Errorf("Unexpected subkey ID: %x", subkey.KeyId)
164
+		}
165
+		err = subkey.Serialize(&w)
166
+		if err != nil {
167
+			t.Error(err)
168
+		}
169
+		// Subkey Sig
170
+		p, err = Read(r)
171
+		if err != nil {
172
+			t.Error(err)
173
+		}
174
+		subkeySig := p.(*Signature)
175
+		err = pubkey.VerifyKeySignature(subkey, subkeySig)
176
+		if err != nil {
177
+			t.Error(err)
178
+		}
179
+		err = subkeySig.Serialize(&w)
180
+		if err != nil {
181
+			t.Error(err)
182
+		}
183
+		// Now read back what we've written again
184
+		r = bytes.NewBuffer(w.Bytes())
185
+		w.Reset()
186
+	}
187
+}
188
+
189
+const rsaFingerprintHex = "5fb74b1d03b1e3cb31bc2f8aa34d7e18c20c31bb"
190
+
191
+const rsaPkDataHex = "988d044d3c5c10010400b1d13382944bd5aba23a4312968b5095d14f947f600eb478e14a6fcb16b0e0cac764884909c020bc495cfcc39a935387c661507bdb236a0612fb582cac3af9b29cc2c8c70090616c41b662f4da4c1201e195472eb7f4ae1ccbcbf9940fe21d985e379a5563dde5b9a23d35f1cfaa5790da3b79db26f23695107bfaca8e7b5bcd0011010001"
192
+
193
+const dsaFingerprintHex = "eece4c094db002103714c63c8e8fbe54062f19ed"
194
+
195
+const dsaPkDataHex = "9901a2044d432f89110400cd581334f0d7a1e1bdc8b9d6d8c0baf68793632735d2bb0903224cbaa1dfbf35a60ee7a13b92643421e1eb41aa8d79bea19a115a677f6b8ba3c7818ce53a6c2a24a1608bd8b8d6e55c5090cbde09dd26e356267465ae25e69ec8bdd57c7bbb2623e4d73336f73a0a9098f7f16da2e25252130fd694c0e8070c55a812a423ae7f00a0ebf50e70c2f19c3520a551bd4b08d30f23530d3d03ff7d0bf4a53a64a09dc5e6e6e35854b7d70c882b0c60293401958b1bd9e40abec3ea05ba87cf64899299d4bd6aa7f459c201d3fbbd6c82004bdc5e8a9eb8082d12054cc90fa9d4ec251a843236a588bf49552441817436c4f43326966fe85447d4e6d0acf8fa1ef0f014730770603ad7634c3088dc52501c237328417c31c89ed70400b2f1a98b0bf42f11fefc430704bebbaa41d9f355600c3facee1e490f64208e0e094ea55e3a598a219a58500bf78ac677b670a14f4e47e9cf8eab4f368cc1ddcaa18cc59309d4cc62dd4f680e73e6cc3e1ce87a84d0925efbcb26c575c093fc42eecf45135fabf6403a25c2016e1774c0484e440a18319072c617cc97ac0a3bb0"
196
+
197
+const ecdsaFingerprintHex = "9892270b38b8980b05c8d56d43fe956c542ca00b"
198
+
199
+const ecdsaPkDataHex = "9893045071c29413052b8104002304230401f4867769cedfa52c325018896245443968e52e51d0c2df8d939949cb5b330f2921711fbee1c9b9dddb95d15cb0255e99badeddda7cc23d9ddcaacbc290969b9f24019375d61c2e4e3b36953a28d8b2bc95f78c3f1d592fb24499be348656a7b17e3963187b4361afe497bc5f9f81213f04069f8e1fb9e6a6290ae295ca1a92b894396cb4"
200
+
201
+// Source: https://sites.google.com/site/brainhub/pgpecckeys#TOC-ECC-NIST-P-384-key
202
+const ecc384PubHex = `99006f044d53059213052b81040022030304f6b8c5aced5b84ef9f4a209db2e4a9dfb70d28cb8c10ecd57674a9fa5a67389942b62d5e51367df4c7bfd3f8e500feecf07ed265a621a8ebbbe53e947ec78c677eba143bd1533c2b350e1c29f82313e1e1108eba063be1e64b10e6950e799c2db42465635f6473615f64685f333834203c6f70656e70677040627261696e6875622e6f72673e8900cb04101309005305024d530592301480000000002000077072656665727265642d656d61696c2d656e636f64696e67407067702e636f6d7067706d696d65040b090807021901051b03000000021602051e010000000415090a08000a0910098033880f54719fca2b0180aa37350968bd5f115afd8ce7bc7b103822152dbff06d0afcda835329510905b98cb469ba208faab87c7412b799e7b633017f58364ea480e8a1a3f253a0c5f22c446e8be9a9fce6210136ee30811abbd49139de28b5bdf8dc36d06ae748579e9ff503b90073044d53059212052b810400220303042faa84024a20b6735c4897efa5bfb41bf85b7eefeab5ca0cb9ffc8ea04a46acb25534a577694f9e25340a4ab5223a9dd1eda530c8aa2e6718db10d7e672558c7736fe09369ea5739a2a3554bf16d41faa50562f11c6d39bbd5dffb6b9a9ec9180301090989008404181309000c05024d530592051b0c000000000a0910098033880f54719f80970180eee7a6d8fcee41ee4f9289df17f9bcf9d955dca25c583b94336f3a2b2d4986dc5cf417b8d2dc86f741a9e1a6d236c0e3017d1c76575458a0cfb93ae8a2b274fcc65ceecd7a91eec83656ba13219969f06945b48c56bd04152c3a0553c5f2f4bd1267`

+ 279
- 0
vendor/src/golang.org/x/crypto/openpgp/packet/public_key_v3.go 查看文件

@@ -0,0 +1,279 @@
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
+
5
+package packet
6
+
7
+import (
8
+	"crypto"
9
+	"crypto/md5"
10
+	"crypto/rsa"
11
+	"encoding/binary"
12
+	"fmt"
13
+	"hash"
14
+	"io"
15
+	"math/big"
16
+	"strconv"
17
+	"time"
18
+
19
+	"golang.org/x/crypto/openpgp/errors"
20
+)
21
+
22
+// PublicKeyV3 represents older, version 3 public keys. These keys are less secure and
23
+// should not be used for signing or encrypting. They are supported here only for
24
+// parsing version 3 key material and validating signatures.
25
+// See RFC 4880, section 5.5.2.
26
+type PublicKeyV3 struct {
27
+	CreationTime time.Time
28
+	DaysToExpire uint16
29
+	PubKeyAlgo   PublicKeyAlgorithm
30
+	PublicKey    *rsa.PublicKey
31
+	Fingerprint  [16]byte
32
+	KeyId        uint64
33
+	IsSubkey     bool
34
+
35
+	n, e parsedMPI
36
+}
37
+
38
+// newRSAPublicKeyV3 returns a PublicKey that wraps the given rsa.PublicKey.
39
+// Included here for testing purposes only. RFC 4880, section 5.5.2:
40
+// "an implementation MUST NOT generate a V3 key, but MAY accept it."
41
+func newRSAPublicKeyV3(creationTime time.Time, pub *rsa.PublicKey) *PublicKeyV3 {
42
+	pk := &PublicKeyV3{
43
+		CreationTime: creationTime,
44
+		PublicKey:    pub,
45
+		n:            fromBig(pub.N),
46
+		e:            fromBig(big.NewInt(int64(pub.E))),
47
+	}
48
+
49
+	pk.setFingerPrintAndKeyId()
50
+	return pk
51
+}
52
+
53
+func (pk *PublicKeyV3) parse(r io.Reader) (err error) {
54
+	// RFC 4880, section 5.5.2
55
+	var buf [8]byte
56
+	if _, err = readFull(r, buf[:]); err != nil {
57
+		return
58
+	}
59
+	if buf[0] < 2 || buf[0] > 3 {
60
+		return errors.UnsupportedError("public key version")
61
+	}
62
+	pk.CreationTime = time.Unix(int64(uint32(buf[1])<<24|uint32(buf[2])<<16|uint32(buf[3])<<8|uint32(buf[4])), 0)
63
+	pk.DaysToExpire = binary.BigEndian.Uint16(buf[5:7])
64
+	pk.PubKeyAlgo = PublicKeyAlgorithm(buf[7])
65
+	switch pk.PubKeyAlgo {
66
+	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
67
+		err = pk.parseRSA(r)
68
+	default:
69
+		err = errors.UnsupportedError("public key type: " + strconv.Itoa(int(pk.PubKeyAlgo)))
70
+	}
71
+	if err != nil {
72
+		return
73
+	}
74
+
75
+	pk.setFingerPrintAndKeyId()
76
+	return
77
+}
78
+
79
+func (pk *PublicKeyV3) setFingerPrintAndKeyId() {
80
+	// RFC 4880, section 12.2
81
+	fingerPrint := md5.New()
82
+	fingerPrint.Write(pk.n.bytes)
83
+	fingerPrint.Write(pk.e.bytes)
84
+	fingerPrint.Sum(pk.Fingerprint[:0])
85
+	pk.KeyId = binary.BigEndian.Uint64(pk.n.bytes[len(pk.n.bytes)-8:])
86
+}
87
+
88
+// parseRSA parses RSA public key material from the given Reader. See RFC 4880,
89
+// section 5.5.2.
90
+func (pk *PublicKeyV3) parseRSA(r io.Reader) (err error) {
91
+	if pk.n.bytes, pk.n.bitLength, err = readMPI(r); err != nil {
92
+		return
93
+	}
94
+	if pk.e.bytes, pk.e.bitLength, err = readMPI(r); err != nil {
95
+		return
96
+	}
97
+
98
+	// RFC 4880 Section 12.2 requires the low 8 bytes of the
99
+	// modulus to form the key id.
100
+	if len(pk.n.bytes) < 8 {
101
+		return errors.StructuralError("v3 public key modulus is too short")
102
+	}
103
+	if len(pk.e.bytes) > 3 {
104
+		err = errors.UnsupportedError("large public exponent")
105
+		return
106
+	}
107
+	rsa := &rsa.PublicKey{N: new(big.Int).SetBytes(pk.n.bytes)}
108
+	for i := 0; i < len(pk.e.bytes); i++ {
109
+		rsa.E <<= 8
110
+		rsa.E |= int(pk.e.bytes[i])
111
+	}
112
+	pk.PublicKey = rsa
113
+	return
114
+}
115
+
116
+// SerializeSignaturePrefix writes the prefix for this public key to the given Writer.
117
+// The prefix is used when calculating a signature over this public key. See
118
+// RFC 4880, section 5.2.4.
119
+func (pk *PublicKeyV3) SerializeSignaturePrefix(w io.Writer) {
120
+	var pLength uint16
121
+	switch pk.PubKeyAlgo {
122
+	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
123
+		pLength += 2 + uint16(len(pk.n.bytes))
124
+		pLength += 2 + uint16(len(pk.e.bytes))
125
+	default:
126
+		panic("unknown public key algorithm")
127
+	}
128
+	pLength += 6
129
+	w.Write([]byte{0x99, byte(pLength >> 8), byte(pLength)})
130
+	return
131
+}
132
+
133
+func (pk *PublicKeyV3) Serialize(w io.Writer) (err error) {
134
+	length := 8 // 8 byte header
135
+
136
+	switch pk.PubKeyAlgo {
137
+	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
138
+		length += 2 + len(pk.n.bytes)
139
+		length += 2 + len(pk.e.bytes)
140
+	default:
141
+		panic("unknown public key algorithm")
142
+	}
143
+
144
+	packetType := packetTypePublicKey
145
+	if pk.IsSubkey {
146
+		packetType = packetTypePublicSubkey
147
+	}
148
+	if err = serializeHeader(w, packetType, length); err != nil {
149
+		return
150
+	}
151
+	return pk.serializeWithoutHeaders(w)
152
+}
153
+
154
+// serializeWithoutHeaders marshals the PublicKey to w in the form of an
155
+// OpenPGP public key packet, not including the packet header.
156
+func (pk *PublicKeyV3) serializeWithoutHeaders(w io.Writer) (err error) {
157
+	var buf [8]byte
158
+	// Version 3
159
+	buf[0] = 3
160
+	// Creation time
161
+	t := uint32(pk.CreationTime.Unix())
162
+	buf[1] = byte(t >> 24)
163
+	buf[2] = byte(t >> 16)
164
+	buf[3] = byte(t >> 8)
165
+	buf[4] = byte(t)
166
+	// Days to expire
167
+	buf[5] = byte(pk.DaysToExpire >> 8)
168
+	buf[6] = byte(pk.DaysToExpire)
169
+	// Public key algorithm
170
+	buf[7] = byte(pk.PubKeyAlgo)
171
+
172
+	if _, err = w.Write(buf[:]); err != nil {
173
+		return
174
+	}
175
+
176
+	switch pk.PubKeyAlgo {
177
+	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
178
+		return writeMPIs(w, pk.n, pk.e)
179
+	}
180
+	return errors.InvalidArgumentError("bad public-key algorithm")
181
+}
182
+
183
+// CanSign returns true iff this public key can generate signatures
184
+func (pk *PublicKeyV3) CanSign() bool {
185
+	return pk.PubKeyAlgo != PubKeyAlgoRSAEncryptOnly
186
+}
187
+
188
+// VerifySignatureV3 returns nil iff sig is a valid signature, made by this
189
+// public key, of the data hashed into signed. signed is mutated by this call.
190
+func (pk *PublicKeyV3) VerifySignatureV3(signed hash.Hash, sig *SignatureV3) (err error) {
191
+	if !pk.CanSign() {
192
+		return errors.InvalidArgumentError("public key cannot generate signatures")
193
+	}
194
+
195
+	suffix := make([]byte, 5)
196
+	suffix[0] = byte(sig.SigType)
197
+	binary.BigEndian.PutUint32(suffix[1:], uint32(sig.CreationTime.Unix()))
198
+	signed.Write(suffix)
199
+	hashBytes := signed.Sum(nil)
200
+
201
+	if hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1] {
202
+		return errors.SignatureError("hash tag doesn't match")
203
+	}
204
+
205
+	if pk.PubKeyAlgo != sig.PubKeyAlgo {
206
+		return errors.InvalidArgumentError("public key and signature use different algorithms")
207
+	}
208
+
209
+	switch pk.PubKeyAlgo {
210
+	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
211
+		if err = rsa.VerifyPKCS1v15(pk.PublicKey, sig.Hash, hashBytes, sig.RSASignature.bytes); err != nil {
212
+			return errors.SignatureError("RSA verification failure")
213
+		}
214
+		return
215
+	default:
216
+		// V3 public keys only support RSA.
217
+		panic("shouldn't happen")
218
+	}
219
+}
220
+
221
+// VerifyUserIdSignatureV3 returns nil iff sig is a valid signature, made by this
222
+// public key, that id is the identity of pub.
223
+func (pk *PublicKeyV3) VerifyUserIdSignatureV3(id string, pub *PublicKeyV3, sig *SignatureV3) (err error) {
224
+	h, err := userIdSignatureV3Hash(id, pk, sig.Hash)
225
+	if err != nil {
226
+		return err
227
+	}
228
+	return pk.VerifySignatureV3(h, sig)
229
+}
230
+
231
+// VerifyKeySignatureV3 returns nil iff sig is a valid signature, made by this
232
+// public key, of signed.
233
+func (pk *PublicKeyV3) VerifyKeySignatureV3(signed *PublicKeyV3, sig *SignatureV3) (err error) {
234
+	h, err := keySignatureHash(pk, signed, sig.Hash)
235
+	if err != nil {
236
+		return err
237
+	}
238
+	return pk.VerifySignatureV3(h, sig)
239
+}
240
+
241
+// userIdSignatureV3Hash returns a Hash of the message that needs to be signed
242
+// to assert that pk is a valid key for id.
243
+func userIdSignatureV3Hash(id string, pk signingKey, hfn crypto.Hash) (h hash.Hash, err error) {
244
+	if !hfn.Available() {
245
+		return nil, errors.UnsupportedError("hash function")
246
+	}
247
+	h = hfn.New()
248
+
249
+	// RFC 4880, section 5.2.4
250
+	pk.SerializeSignaturePrefix(h)
251
+	pk.serializeWithoutHeaders(h)
252
+
253
+	h.Write([]byte(id))
254
+
255
+	return
256
+}
257
+
258
+// KeyIdString returns the public key's fingerprint in capital hex
259
+// (e.g. "6C7EE1B8621CC013").
260
+func (pk *PublicKeyV3) KeyIdString() string {
261
+	return fmt.Sprintf("%X", pk.KeyId)
262
+}
263
+
264
+// KeyIdShortString returns the short form of public key's fingerprint
265
+// in capital hex, as shown by gpg --list-keys (e.g. "621CC013").
266
+func (pk *PublicKeyV3) KeyIdShortString() string {
267
+	return fmt.Sprintf("%X", pk.KeyId&0xFFFFFFFF)
268
+}
269
+
270
+// BitLength returns the bit length for the given public key.
271
+func (pk *PublicKeyV3) BitLength() (bitLength uint16, err error) {
272
+	switch pk.PubKeyAlgo {
273
+	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
274
+		bitLength = pk.n.bitLength
275
+	default:
276
+		err = errors.InvalidArgumentError("bad public-key algorithm")
277
+	}
278
+	return
279
+}

+ 82
- 0
vendor/src/golang.org/x/crypto/openpgp/packet/public_key_v3_test.go 查看文件

@@ -0,0 +1,82 @@
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
+
5
+package packet
6
+
7
+import (
8
+	"bytes"
9
+	"encoding/hex"
10
+	"testing"
11
+	"time"
12
+)
13
+
14
+var pubKeyV3Test = struct {
15
+	hexFingerprint string
16
+	creationTime   time.Time
17
+	pubKeyAlgo     PublicKeyAlgorithm
18
+	keyId          uint64
19
+	keyIdString    string
20
+	keyIdShort     string
21
+}{
22
+	"103BECF5BD1E837C89D19E98487767F7",
23
+	time.Unix(779753634, 0),
24
+	PubKeyAlgoRSA,
25
+	0xDE0F188A5DA5E3C9,
26
+	"DE0F188A5DA5E3C9",
27
+	"5DA5E3C9"}
28
+
29
+func TestPublicKeyV3Read(t *testing.T) {
30
+	i, test := 0, pubKeyV3Test
31
+	packet, err := Read(v3KeyReader(t))
32
+	if err != nil {
33
+		t.Fatalf("#%d: Read error: %s", i, err)
34
+	}
35
+	pk, ok := packet.(*PublicKeyV3)
36
+	if !ok {
37
+		t.Fatalf("#%d: failed to parse, got: %#v", i, packet)
38
+	}
39
+	if pk.PubKeyAlgo != test.pubKeyAlgo {
40
+		t.Errorf("#%d: bad public key algorithm got:%x want:%x", i, pk.PubKeyAlgo, test.pubKeyAlgo)
41
+	}
42
+	if !pk.CreationTime.Equal(test.creationTime) {
43
+		t.Errorf("#%d: bad creation time got:%v want:%v", i, pk.CreationTime, test.creationTime)
44
+	}
45
+	expectedFingerprint, _ := hex.DecodeString(test.hexFingerprint)
46
+	if !bytes.Equal(expectedFingerprint, pk.Fingerprint[:]) {
47
+		t.Errorf("#%d: bad fingerprint got:%x want:%x", i, pk.Fingerprint[:], expectedFingerprint)
48
+	}
49
+	if pk.KeyId != test.keyId {
50
+		t.Errorf("#%d: bad keyid got:%x want:%x", i, pk.KeyId, test.keyId)
51
+	}
52
+	if g, e := pk.KeyIdString(), test.keyIdString; g != e {
53
+		t.Errorf("#%d: bad KeyIdString got:%q want:%q", i, g, e)
54
+	}
55
+	if g, e := pk.KeyIdShortString(), test.keyIdShort; g != e {
56
+		t.Errorf("#%d: bad KeyIdShortString got:%q want:%q", i, g, e)
57
+	}
58
+}
59
+
60
+func TestPublicKeyV3Serialize(t *testing.T) {
61
+	//for i, test := range pubKeyV3Tests {
62
+	i := 0
63
+	packet, err := Read(v3KeyReader(t))
64
+	if err != nil {
65
+		t.Fatalf("#%d: Read error: %s", i, err)
66
+	}
67
+	pk, ok := packet.(*PublicKeyV3)
68
+	if !ok {
69
+		t.Fatalf("#%d: failed to parse, got: %#v", i, packet)
70
+	}
71
+	var serializeBuf bytes.Buffer
72
+	if err = pk.Serialize(&serializeBuf); err != nil {
73
+		t.Fatalf("#%d: failed to serialize: %s", i, err)
74
+	}
75
+
76
+	if packet, err = Read(bytes.NewBuffer(serializeBuf.Bytes())); err != nil {
77
+		t.Fatalf("#%d: Read error (from serialized data): %s", i, err)
78
+	}
79
+	if pk, ok = packet.(*PublicKeyV3); !ok {
80
+		t.Fatalf("#%d: failed to parse serialized data, got: %#v", i, packet)
81
+	}
82
+}

+ 76
- 0
vendor/src/golang.org/x/crypto/openpgp/packet/reader.go 查看文件

@@ -0,0 +1,76 @@
1
+// Copyright 2011 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
+
5
+package packet
6
+
7
+import (
8
+	"golang.org/x/crypto/openpgp/errors"
9
+	"io"
10
+)
11
+
12
+// Reader reads packets from an io.Reader and allows packets to be 'unread' so
13
+// that they result from the next call to Next.
14
+type Reader struct {
15
+	q       []Packet
16
+	readers []io.Reader
17
+}
18
+
19
+// New io.Readers are pushed when a compressed or encrypted packet is processed
20
+// and recursively treated as a new source of packets. However, a carefully
21
+// crafted packet can trigger an infinite recursive sequence of packets. See
22
+// http://mumble.net/~campbell/misc/pgp-quine
23
+// https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2013-4402
24
+// This constant limits the number of recursive packets that may be pushed.
25
+const maxReaders = 32
26
+
27
+// Next returns the most recently unread Packet, or reads another packet from
28
+// the top-most io.Reader. Unknown packet types are skipped.
29
+func (r *Reader) Next() (p Packet, err error) {
30
+	if len(r.q) > 0 {
31
+		p = r.q[len(r.q)-1]
32
+		r.q = r.q[:len(r.q)-1]
33
+		return
34
+	}
35
+
36
+	for len(r.readers) > 0 {
37
+		p, err = Read(r.readers[len(r.readers)-1])
38
+		if err == nil {
39
+			return
40
+		}
41
+		if err == io.EOF {
42
+			r.readers = r.readers[:len(r.readers)-1]
43
+			continue
44
+		}
45
+		if _, ok := err.(errors.UnknownPacketTypeError); !ok {
46
+			return nil, err
47
+		}
48
+	}
49
+
50
+	return nil, io.EOF
51
+}
52
+
53
+// Push causes the Reader to start reading from a new io.Reader. When an EOF
54
+// error is seen from the new io.Reader, it is popped and the Reader continues
55
+// to read from the next most recent io.Reader. Push returns a StructuralError
56
+// if pushing the reader would exceed the maximum recursion level, otherwise it
57
+// returns nil.
58
+func (r *Reader) Push(reader io.Reader) (err error) {
59
+	if len(r.readers) >= maxReaders {
60
+		return errors.StructuralError("too many layers of packets")
61
+	}
62
+	r.readers = append(r.readers, reader)
63
+	return nil
64
+}
65
+
66
+// Unread causes the given Packet to be returned from the next call to Next.
67
+func (r *Reader) Unread(p Packet) {
68
+	r.q = append(r.q, p)
69
+}
70
+
71
+func NewReader(r io.Reader) *Reader {
72
+	return &Reader{
73
+		q:       nil,
74
+		readers: []io.Reader{r},
75
+	}
76
+}

+ 731
- 0
vendor/src/golang.org/x/crypto/openpgp/packet/signature.go 查看文件

@@ -0,0 +1,731 @@
1
+// Copyright 2011 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
+
5
+package packet
6
+
7
+import (
8
+	"bytes"
9
+	"crypto"
10
+	"crypto/dsa"
11
+	"crypto/ecdsa"
12
+	"encoding/asn1"
13
+	"encoding/binary"
14
+	"hash"
15
+	"io"
16
+	"math/big"
17
+	"strconv"
18
+	"time"
19
+
20
+	"golang.org/x/crypto/openpgp/errors"
21
+	"golang.org/x/crypto/openpgp/s2k"
22
+)
23
+
24
+const (
25
+	// See RFC 4880, section 5.2.3.21 for details.
26
+	KeyFlagCertify = 1 << iota
27
+	KeyFlagSign
28
+	KeyFlagEncryptCommunications
29
+	KeyFlagEncryptStorage
30
+)
31
+
32
+// Signature represents a signature. See RFC 4880, section 5.2.
33
+type Signature struct {
34
+	SigType    SignatureType
35
+	PubKeyAlgo PublicKeyAlgorithm
36
+	Hash       crypto.Hash
37
+
38
+	// HashSuffix is extra data that is hashed in after the signed data.
39
+	HashSuffix []byte
40
+	// HashTag contains the first two bytes of the hash for fast rejection
41
+	// of bad signed data.
42
+	HashTag      [2]byte
43
+	CreationTime time.Time
44
+
45
+	RSASignature         parsedMPI
46
+	DSASigR, DSASigS     parsedMPI
47
+	ECDSASigR, ECDSASigS parsedMPI
48
+
49
+	// rawSubpackets contains the unparsed subpackets, in order.
50
+	rawSubpackets []outputSubpacket
51
+
52
+	// The following are optional so are nil when not included in the
53
+	// signature.
54
+
55
+	SigLifetimeSecs, KeyLifetimeSecs                        *uint32
56
+	PreferredSymmetric, PreferredHash, PreferredCompression []uint8
57
+	IssuerKeyId                                             *uint64
58
+	IsPrimaryId                                             *bool
59
+
60
+	// FlagsValid is set if any flags were given. See RFC 4880, section
61
+	// 5.2.3.21 for details.
62
+	FlagsValid                                                           bool
63
+	FlagCertify, FlagSign, FlagEncryptCommunications, FlagEncryptStorage bool
64
+
65
+	// RevocationReason is set if this signature has been revoked.
66
+	// See RFC 4880, section 5.2.3.23 for details.
67
+	RevocationReason     *uint8
68
+	RevocationReasonText string
69
+
70
+	// MDC is set if this signature has a feature packet that indicates
71
+	// support for MDC subpackets.
72
+	MDC bool
73
+
74
+	// EmbeddedSignature, if non-nil, is a signature of the parent key, by
75
+	// this key. This prevents an attacker from claiming another's signing
76
+	// subkey as their own.
77
+	EmbeddedSignature *Signature
78
+
79
+	outSubpackets []outputSubpacket
80
+}
81
+
82
+func (sig *Signature) parse(r io.Reader) (err error) {
83
+	// RFC 4880, section 5.2.3
84
+	var buf [5]byte
85
+	_, err = readFull(r, buf[:1])
86
+	if err != nil {
87
+		return
88
+	}
89
+	if buf[0] != 4 {
90
+		err = errors.UnsupportedError("signature packet version " + strconv.Itoa(int(buf[0])))
91
+		return
92
+	}
93
+
94
+	_, err = readFull(r, buf[:5])
95
+	if err != nil {
96
+		return
97
+	}
98
+	sig.SigType = SignatureType(buf[0])
99
+	sig.PubKeyAlgo = PublicKeyAlgorithm(buf[1])
100
+	switch sig.PubKeyAlgo {
101
+	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoDSA, PubKeyAlgoECDSA:
102
+	default:
103
+		err = errors.UnsupportedError("public key algorithm " + strconv.Itoa(int(sig.PubKeyAlgo)))
104
+		return
105
+	}
106
+
107
+	var ok bool
108
+	sig.Hash, ok = s2k.HashIdToHash(buf[2])
109
+	if !ok {
110
+		return errors.UnsupportedError("hash function " + strconv.Itoa(int(buf[2])))
111
+	}
112
+
113
+	hashedSubpacketsLength := int(buf[3])<<8 | int(buf[4])
114
+	l := 6 + hashedSubpacketsLength
115
+	sig.HashSuffix = make([]byte, l+6)
116
+	sig.HashSuffix[0] = 4
117
+	copy(sig.HashSuffix[1:], buf[:5])
118
+	hashedSubpackets := sig.HashSuffix[6:l]
119
+	_, err = readFull(r, hashedSubpackets)
120
+	if err != nil {
121
+		return
122
+	}
123
+	// See RFC 4880, section 5.2.4
124
+	trailer := sig.HashSuffix[l:]
125
+	trailer[0] = 4
126
+	trailer[1] = 0xff
127
+	trailer[2] = uint8(l >> 24)
128
+	trailer[3] = uint8(l >> 16)
129
+	trailer[4] = uint8(l >> 8)
130
+	trailer[5] = uint8(l)
131
+
132
+	err = parseSignatureSubpackets(sig, hashedSubpackets, true)
133
+	if err != nil {
134
+		return
135
+	}
136
+
137
+	_, err = readFull(r, buf[:2])
138
+	if err != nil {
139
+		return
140
+	}
141
+	unhashedSubpacketsLength := int(buf[0])<<8 | int(buf[1])
142
+	unhashedSubpackets := make([]byte, unhashedSubpacketsLength)
143
+	_, err = readFull(r, unhashedSubpackets)
144
+	if err != nil {
145
+		return
146
+	}
147
+	err = parseSignatureSubpackets(sig, unhashedSubpackets, false)
148
+	if err != nil {
149
+		return
150
+	}
151
+
152
+	_, err = readFull(r, sig.HashTag[:2])
153
+	if err != nil {
154
+		return
155
+	}
156
+
157
+	switch sig.PubKeyAlgo {
158
+	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
159
+		sig.RSASignature.bytes, sig.RSASignature.bitLength, err = readMPI(r)
160
+	case PubKeyAlgoDSA:
161
+		sig.DSASigR.bytes, sig.DSASigR.bitLength, err = readMPI(r)
162
+		if err == nil {
163
+			sig.DSASigS.bytes, sig.DSASigS.bitLength, err = readMPI(r)
164
+		}
165
+	case PubKeyAlgoECDSA:
166
+		sig.ECDSASigR.bytes, sig.ECDSASigR.bitLength, err = readMPI(r)
167
+		if err == nil {
168
+			sig.ECDSASigS.bytes, sig.ECDSASigS.bitLength, err = readMPI(r)
169
+		}
170
+	default:
171
+		panic("unreachable")
172
+	}
173
+	return
174
+}
175
+
176
+// parseSignatureSubpackets parses subpackets of the main signature packet. See
177
+// RFC 4880, section 5.2.3.1.
178
+func parseSignatureSubpackets(sig *Signature, subpackets []byte, isHashed bool) (err error) {
179
+	for len(subpackets) > 0 {
180
+		subpackets, err = parseSignatureSubpacket(sig, subpackets, isHashed)
181
+		if err != nil {
182
+			return
183
+		}
184
+	}
185
+
186
+	if sig.CreationTime.IsZero() {
187
+		err = errors.StructuralError("no creation time in signature")
188
+	}
189
+
190
+	return
191
+}
192
+
193
+type signatureSubpacketType uint8
194
+
195
+const (
196
+	creationTimeSubpacket        signatureSubpacketType = 2
197
+	signatureExpirationSubpacket signatureSubpacketType = 3
198
+	keyExpirationSubpacket       signatureSubpacketType = 9
199
+	prefSymmetricAlgosSubpacket  signatureSubpacketType = 11
200
+	issuerSubpacket              signatureSubpacketType = 16
201
+	prefHashAlgosSubpacket       signatureSubpacketType = 21
202
+	prefCompressionSubpacket     signatureSubpacketType = 22
203
+	primaryUserIdSubpacket       signatureSubpacketType = 25
204
+	keyFlagsSubpacket            signatureSubpacketType = 27
205
+	reasonForRevocationSubpacket signatureSubpacketType = 29
206
+	featuresSubpacket            signatureSubpacketType = 30
207
+	embeddedSignatureSubpacket   signatureSubpacketType = 32
208
+)
209
+
210
+// parseSignatureSubpacket parses a single subpacket. len(subpacket) is >= 1.
211
+func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (rest []byte, err error) {
212
+	// RFC 4880, section 5.2.3.1
213
+	var (
214
+		length     uint32
215
+		packetType signatureSubpacketType
216
+		isCritical bool
217
+	)
218
+	switch {
219
+	case subpacket[0] < 192:
220
+		length = uint32(subpacket[0])
221
+		subpacket = subpacket[1:]
222
+	case subpacket[0] < 255:
223
+		if len(subpacket) < 2 {
224
+			goto Truncated
225
+		}
226
+		length = uint32(subpacket[0]-192)<<8 + uint32(subpacket[1]) + 192
227
+		subpacket = subpacket[2:]
228
+	default:
229
+		if len(subpacket) < 5 {
230
+			goto Truncated
231
+		}
232
+		length = uint32(subpacket[1])<<24 |
233
+			uint32(subpacket[2])<<16 |
234
+			uint32(subpacket[3])<<8 |
235
+			uint32(subpacket[4])
236
+		subpacket = subpacket[5:]
237
+	}
238
+	if length > uint32(len(subpacket)) {
239
+		goto Truncated
240
+	}
241
+	rest = subpacket[length:]
242
+	subpacket = subpacket[:length]
243
+	if len(subpacket) == 0 {
244
+		err = errors.StructuralError("zero length signature subpacket")
245
+		return
246
+	}
247
+	packetType = signatureSubpacketType(subpacket[0] & 0x7f)
248
+	isCritical = subpacket[0]&0x80 == 0x80
249
+	subpacket = subpacket[1:]
250
+	sig.rawSubpackets = append(sig.rawSubpackets, outputSubpacket{isHashed, packetType, isCritical, subpacket})
251
+	switch packetType {
252
+	case creationTimeSubpacket:
253
+		if !isHashed {
254
+			err = errors.StructuralError("signature creation time in non-hashed area")
255
+			return
256
+		}
257
+		if len(subpacket) != 4 {
258
+			err = errors.StructuralError("signature creation time not four bytes")
259
+			return
260
+		}
261
+		t := binary.BigEndian.Uint32(subpacket)
262
+		sig.CreationTime = time.Unix(int64(t), 0)
263
+	case signatureExpirationSubpacket:
264
+		// Signature expiration time, section 5.2.3.10
265
+		if !isHashed {
266
+			return
267
+		}
268
+		if len(subpacket) != 4 {
269
+			err = errors.StructuralError("expiration subpacket with bad length")
270
+			return
271
+		}
272
+		sig.SigLifetimeSecs = new(uint32)
273
+		*sig.SigLifetimeSecs = binary.BigEndian.Uint32(subpacket)
274
+	case keyExpirationSubpacket:
275
+		// Key expiration time, section 5.2.3.6
276
+		if !isHashed {
277
+			return
278
+		}
279
+		if len(subpacket) != 4 {
280
+			err = errors.StructuralError("key expiration subpacket with bad length")
281
+			return
282
+		}
283
+		sig.KeyLifetimeSecs = new(uint32)
284
+		*sig.KeyLifetimeSecs = binary.BigEndian.Uint32(subpacket)
285
+	case prefSymmetricAlgosSubpacket:
286
+		// Preferred symmetric algorithms, section 5.2.3.7
287
+		if !isHashed {
288
+			return
289
+		}
290
+		sig.PreferredSymmetric = make([]byte, len(subpacket))
291
+		copy(sig.PreferredSymmetric, subpacket)
292
+	case issuerSubpacket:
293
+		// Issuer, section 5.2.3.5
294
+		if len(subpacket) != 8 {
295
+			err = errors.StructuralError("issuer subpacket with bad length")
296
+			return
297
+		}
298
+		sig.IssuerKeyId = new(uint64)
299
+		*sig.IssuerKeyId = binary.BigEndian.Uint64(subpacket)
300
+	case prefHashAlgosSubpacket:
301
+		// Preferred hash algorithms, section 5.2.3.8
302
+		if !isHashed {
303
+			return
304
+		}
305
+		sig.PreferredHash = make([]byte, len(subpacket))
306
+		copy(sig.PreferredHash, subpacket)
307
+	case prefCompressionSubpacket:
308
+		// Preferred compression algorithms, section 5.2.3.9
309
+		if !isHashed {
310
+			return
311
+		}
312
+		sig.PreferredCompression = make([]byte, len(subpacket))
313
+		copy(sig.PreferredCompression, subpacket)
314
+	case primaryUserIdSubpacket:
315
+		// Primary User ID, section 5.2.3.19
316
+		if !isHashed {
317
+			return
318
+		}
319
+		if len(subpacket) != 1 {
320
+			err = errors.StructuralError("primary user id subpacket with bad length")
321
+			return
322
+		}
323
+		sig.IsPrimaryId = new(bool)
324
+		if subpacket[0] > 0 {
325
+			*sig.IsPrimaryId = true
326
+		}
327
+	case keyFlagsSubpacket:
328
+		// Key flags, section 5.2.3.21
329
+		if !isHashed {
330
+			return
331
+		}
332
+		if len(subpacket) == 0 {
333
+			err = errors.StructuralError("empty key flags subpacket")
334
+			return
335
+		}
336
+		sig.FlagsValid = true
337
+		if subpacket[0]&KeyFlagCertify != 0 {
338
+			sig.FlagCertify = true
339
+		}
340
+		if subpacket[0]&KeyFlagSign != 0 {
341
+			sig.FlagSign = true
342
+		}
343
+		if subpacket[0]&KeyFlagEncryptCommunications != 0 {
344
+			sig.FlagEncryptCommunications = true
345
+		}
346
+		if subpacket[0]&KeyFlagEncryptStorage != 0 {
347
+			sig.FlagEncryptStorage = true
348
+		}
349
+	case reasonForRevocationSubpacket:
350
+		// Reason For Revocation, section 5.2.3.23
351
+		if !isHashed {
352
+			return
353
+		}
354
+		if len(subpacket) == 0 {
355
+			err = errors.StructuralError("empty revocation reason subpacket")
356
+			return
357
+		}
358
+		sig.RevocationReason = new(uint8)
359
+		*sig.RevocationReason = subpacket[0]
360
+		sig.RevocationReasonText = string(subpacket[1:])
361
+	case featuresSubpacket:
362
+		// Features subpacket, section 5.2.3.24 specifies a very general
363
+		// mechanism for OpenPGP implementations to signal support for new
364
+		// features. In practice, the subpacket is used exclusively to
365
+		// indicate support for MDC-protected encryption.
366
+		sig.MDC = len(subpacket) >= 1 && subpacket[0]&1 == 1
367
+	case embeddedSignatureSubpacket:
368
+		// Only usage is in signatures that cross-certify
369
+		// signing subkeys. section 5.2.3.26 describes the
370
+		// format, with its usage described in section 11.1
371
+		if sig.EmbeddedSignature != nil {
372
+			err = errors.StructuralError("Cannot have multiple embedded signatures")
373
+			return
374
+		}
375
+		sig.EmbeddedSignature = new(Signature)
376
+		// Embedded signatures are required to be v4 signatures see
377
+		// section 12.1. However, we only parse v4 signatures in this
378
+		// file anyway.
379
+		if err := sig.EmbeddedSignature.parse(bytes.NewBuffer(subpacket)); err != nil {
380
+			return nil, err
381
+		}
382
+		if sigType := sig.EmbeddedSignature.SigType; sigType != SigTypePrimaryKeyBinding {
383
+			return nil, errors.StructuralError("cross-signature has unexpected type " + strconv.Itoa(int(sigType)))
384
+		}
385
+	default:
386
+		if isCritical {
387
+			err = errors.UnsupportedError("unknown critical signature subpacket type " + strconv.Itoa(int(packetType)))
388
+			return
389
+		}
390
+	}
391
+	return
392
+
393
+Truncated:
394
+	err = errors.StructuralError("signature subpacket truncated")
395
+	return
396
+}
397
+
398
+// subpacketLengthLength returns the length, in bytes, of an encoded length value.
399
+func subpacketLengthLength(length int) int {
400
+	if length < 192 {
401
+		return 1
402
+	}
403
+	if length < 16320 {
404
+		return 2
405
+	}
406
+	return 5
407
+}
408
+
409
+// serializeSubpacketLength marshals the given length into to.
410
+func serializeSubpacketLength(to []byte, length int) int {
411
+	// RFC 4880, Section 4.2.2.
412
+	if length < 192 {
413
+		to[0] = byte(length)
414
+		return 1
415
+	}
416
+	if length < 16320 {
417
+		length -= 192
418
+		to[0] = byte((length >> 8) + 192)
419
+		to[1] = byte(length)
420
+		return 2
421
+	}
422
+	to[0] = 255
423
+	to[1] = byte(length >> 24)
424
+	to[2] = byte(length >> 16)
425
+	to[3] = byte(length >> 8)
426
+	to[4] = byte(length)
427
+	return 5
428
+}
429
+
430
+// subpacketsLength returns the serialized length, in bytes, of the given
431
+// subpackets.
432
+func subpacketsLength(subpackets []outputSubpacket, hashed bool) (length int) {
433
+	for _, subpacket := range subpackets {
434
+		if subpacket.hashed == hashed {
435
+			length += subpacketLengthLength(len(subpacket.contents) + 1)
436
+			length += 1 // type byte
437
+			length += len(subpacket.contents)
438
+		}
439
+	}
440
+	return
441
+}
442
+
443
+// serializeSubpackets marshals the given subpackets into to.
444
+func serializeSubpackets(to []byte, subpackets []outputSubpacket, hashed bool) {
445
+	for _, subpacket := range subpackets {
446
+		if subpacket.hashed == hashed {
447
+			n := serializeSubpacketLength(to, len(subpacket.contents)+1)
448
+			to[n] = byte(subpacket.subpacketType)
449
+			to = to[1+n:]
450
+			n = copy(to, subpacket.contents)
451
+			to = to[n:]
452
+		}
453
+	}
454
+	return
455
+}
456
+
457
+// KeyExpired returns whether sig is a self-signature of a key that has
458
+// expired.
459
+func (sig *Signature) KeyExpired(currentTime time.Time) bool {
460
+	if sig.KeyLifetimeSecs == nil {
461
+		return false
462
+	}
463
+	expiry := sig.CreationTime.Add(time.Duration(*sig.KeyLifetimeSecs) * time.Second)
464
+	return currentTime.After(expiry)
465
+}
466
+
467
+// buildHashSuffix constructs the HashSuffix member of sig in preparation for signing.
468
+func (sig *Signature) buildHashSuffix() (err error) {
469
+	hashedSubpacketsLen := subpacketsLength(sig.outSubpackets, true)
470
+
471
+	var ok bool
472
+	l := 6 + hashedSubpacketsLen
473
+	sig.HashSuffix = make([]byte, l+6)
474
+	sig.HashSuffix[0] = 4
475
+	sig.HashSuffix[1] = uint8(sig.SigType)
476
+	sig.HashSuffix[2] = uint8(sig.PubKeyAlgo)
477
+	sig.HashSuffix[3], ok = s2k.HashToHashId(sig.Hash)
478
+	if !ok {
479
+		sig.HashSuffix = nil
480
+		return errors.InvalidArgumentError("hash cannot be represented in OpenPGP: " + strconv.Itoa(int(sig.Hash)))
481
+	}
482
+	sig.HashSuffix[4] = byte(hashedSubpacketsLen >> 8)
483
+	sig.HashSuffix[5] = byte(hashedSubpacketsLen)
484
+	serializeSubpackets(sig.HashSuffix[6:l], sig.outSubpackets, true)
485
+	trailer := sig.HashSuffix[l:]
486
+	trailer[0] = 4
487
+	trailer[1] = 0xff
488
+	trailer[2] = byte(l >> 24)
489
+	trailer[3] = byte(l >> 16)
490
+	trailer[4] = byte(l >> 8)
491
+	trailer[5] = byte(l)
492
+	return
493
+}
494
+
495
+func (sig *Signature) signPrepareHash(h hash.Hash) (digest []byte, err error) {
496
+	err = sig.buildHashSuffix()
497
+	if err != nil {
498
+		return
499
+	}
500
+
501
+	h.Write(sig.HashSuffix)
502
+	digest = h.Sum(nil)
503
+	copy(sig.HashTag[:], digest)
504
+	return
505
+}
506
+
507
+// Sign signs a message with a private key. The hash, h, must contain
508
+// the hash of the message to be signed and will be mutated by this function.
509
+// On success, the signature is stored in sig. Call Serialize to write it out.
510
+// If config is nil, sensible defaults will be used.
511
+func (sig *Signature) Sign(h hash.Hash, priv *PrivateKey, config *Config) (err error) {
512
+	sig.outSubpackets = sig.buildSubpackets()
513
+	digest, err := sig.signPrepareHash(h)
514
+	if err != nil {
515
+		return
516
+	}
517
+
518
+	switch priv.PubKeyAlgo {
519
+	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
520
+		// supports both *rsa.PrivateKey and crypto.Signer
521
+		sig.RSASignature.bytes, err = priv.PrivateKey.(crypto.Signer).Sign(config.Random(), digest, sig.Hash)
522
+		sig.RSASignature.bitLength = uint16(8 * len(sig.RSASignature.bytes))
523
+	case PubKeyAlgoDSA:
524
+		dsaPriv := priv.PrivateKey.(*dsa.PrivateKey)
525
+
526
+		// Need to truncate hashBytes to match FIPS 186-3 section 4.6.
527
+		subgroupSize := (dsaPriv.Q.BitLen() + 7) / 8
528
+		if len(digest) > subgroupSize {
529
+			digest = digest[:subgroupSize]
530
+		}
531
+		r, s, err := dsa.Sign(config.Random(), dsaPriv, digest)
532
+		if err == nil {
533
+			sig.DSASigR.bytes = r.Bytes()
534
+			sig.DSASigR.bitLength = uint16(8 * len(sig.DSASigR.bytes))
535
+			sig.DSASigS.bytes = s.Bytes()
536
+			sig.DSASigS.bitLength = uint16(8 * len(sig.DSASigS.bytes))
537
+		}
538
+	case PubKeyAlgoECDSA:
539
+		var r, s *big.Int
540
+		if pk, ok := priv.PrivateKey.(*ecdsa.PrivateKey); ok {
541
+			// direct support, avoid asn1 wrapping/unwrapping
542
+			r, s, err = ecdsa.Sign(config.Random(), pk, digest)
543
+		} else {
544
+			var b []byte
545
+			b, err = priv.PrivateKey.(crypto.Signer).Sign(config.Random(), digest, nil)
546
+			if err == nil {
547
+				r, s, err = unwrapECDSASig(b)
548
+			}
549
+		}
550
+		if err == nil {
551
+			sig.ECDSASigR = fromBig(r)
552
+			sig.ECDSASigS = fromBig(s)
553
+		}
554
+	default:
555
+		err = errors.UnsupportedError("public key algorithm: " + strconv.Itoa(int(sig.PubKeyAlgo)))
556
+	}
557
+
558
+	return
559
+}
560
+
561
+// unwrapECDSASig parses the two integer components of an ASN.1-encoded ECDSA
562
+// signature.
563
+func unwrapECDSASig(b []byte) (r, s *big.Int, err error) {
564
+	var ecsdaSig struct {
565
+		R, S *big.Int
566
+	}
567
+	_, err = asn1.Unmarshal(b, &ecsdaSig)
568
+	if err != nil {
569
+		return
570
+	}
571
+	return ecsdaSig.R, ecsdaSig.S, nil
572
+}
573
+
574
+// SignUserId computes a signature from priv, asserting that pub is a valid
575
+// key for the identity id.  On success, the signature is stored in sig. Call
576
+// Serialize to write it out.
577
+// If config is nil, sensible defaults will be used.
578
+func (sig *Signature) SignUserId(id string, pub *PublicKey, priv *PrivateKey, config *Config) error {
579
+	h, err := userIdSignatureHash(id, pub, sig.Hash)
580
+	if err != nil {
581
+		return err
582
+	}
583
+	return sig.Sign(h, priv, config)
584
+}
585
+
586
+// SignKey computes a signature from priv, asserting that pub is a subkey. On
587
+// success, the signature is stored in sig. Call Serialize to write it out.
588
+// If config is nil, sensible defaults will be used.
589
+func (sig *Signature) SignKey(pub *PublicKey, priv *PrivateKey, config *Config) error {
590
+	h, err := keySignatureHash(&priv.PublicKey, pub, sig.Hash)
591
+	if err != nil {
592
+		return err
593
+	}
594
+	return sig.Sign(h, priv, config)
595
+}
596
+
597
+// Serialize marshals sig to w. Sign, SignUserId or SignKey must have been
598
+// called first.
599
+func (sig *Signature) Serialize(w io.Writer) (err error) {
600
+	if len(sig.outSubpackets) == 0 {
601
+		sig.outSubpackets = sig.rawSubpackets
602
+	}
603
+	if sig.RSASignature.bytes == nil && sig.DSASigR.bytes == nil && sig.ECDSASigR.bytes == nil {
604
+		return errors.InvalidArgumentError("Signature: need to call Sign, SignUserId or SignKey before Serialize")
605
+	}
606
+
607
+	sigLength := 0
608
+	switch sig.PubKeyAlgo {
609
+	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
610
+		sigLength = 2 + len(sig.RSASignature.bytes)
611
+	case PubKeyAlgoDSA:
612
+		sigLength = 2 + len(sig.DSASigR.bytes)
613
+		sigLength += 2 + len(sig.DSASigS.bytes)
614
+	case PubKeyAlgoECDSA:
615
+		sigLength = 2 + len(sig.ECDSASigR.bytes)
616
+		sigLength += 2 + len(sig.ECDSASigS.bytes)
617
+	default:
618
+		panic("impossible")
619
+	}
620
+
621
+	unhashedSubpacketsLen := subpacketsLength(sig.outSubpackets, false)
622
+	length := len(sig.HashSuffix) - 6 /* trailer not included */ +
623
+		2 /* length of unhashed subpackets */ + unhashedSubpacketsLen +
624
+		2 /* hash tag */ + sigLength
625
+	err = serializeHeader(w, packetTypeSignature, length)
626
+	if err != nil {
627
+		return
628
+	}
629
+
630
+	_, err = w.Write(sig.HashSuffix[:len(sig.HashSuffix)-6])
631
+	if err != nil {
632
+		return
633
+	}
634
+
635
+	unhashedSubpackets := make([]byte, 2+unhashedSubpacketsLen)
636
+	unhashedSubpackets[0] = byte(unhashedSubpacketsLen >> 8)
637
+	unhashedSubpackets[1] = byte(unhashedSubpacketsLen)
638
+	serializeSubpackets(unhashedSubpackets[2:], sig.outSubpackets, false)
639
+
640
+	_, err = w.Write(unhashedSubpackets)
641
+	if err != nil {
642
+		return
643
+	}
644
+	_, err = w.Write(sig.HashTag[:])
645
+	if err != nil {
646
+		return
647
+	}
648
+
649
+	switch sig.PubKeyAlgo {
650
+	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
651
+		err = writeMPIs(w, sig.RSASignature)
652
+	case PubKeyAlgoDSA:
653
+		err = writeMPIs(w, sig.DSASigR, sig.DSASigS)
654
+	case PubKeyAlgoECDSA:
655
+		err = writeMPIs(w, sig.ECDSASigR, sig.ECDSASigS)
656
+	default:
657
+		panic("impossible")
658
+	}
659
+	return
660
+}
661
+
662
+// outputSubpacket represents a subpacket to be marshaled.
663
+type outputSubpacket struct {
664
+	hashed        bool // true if this subpacket is in the hashed area.
665
+	subpacketType signatureSubpacketType
666
+	isCritical    bool
667
+	contents      []byte
668
+}
669
+
670
+func (sig *Signature) buildSubpackets() (subpackets []outputSubpacket) {
671
+	creationTime := make([]byte, 4)
672
+	binary.BigEndian.PutUint32(creationTime, uint32(sig.CreationTime.Unix()))
673
+	subpackets = append(subpackets, outputSubpacket{true, creationTimeSubpacket, false, creationTime})
674
+
675
+	if sig.IssuerKeyId != nil {
676
+		keyId := make([]byte, 8)
677
+		binary.BigEndian.PutUint64(keyId, *sig.IssuerKeyId)
678
+		subpackets = append(subpackets, outputSubpacket{true, issuerSubpacket, false, keyId})
679
+	}
680
+
681
+	if sig.SigLifetimeSecs != nil && *sig.SigLifetimeSecs != 0 {
682
+		sigLifetime := make([]byte, 4)
683
+		binary.BigEndian.PutUint32(sigLifetime, *sig.SigLifetimeSecs)
684
+		subpackets = append(subpackets, outputSubpacket{true, signatureExpirationSubpacket, true, sigLifetime})
685
+	}
686
+
687
+	// Key flags may only appear in self-signatures or certification signatures.
688
+
689
+	if sig.FlagsValid {
690
+		var flags byte
691
+		if sig.FlagCertify {
692
+			flags |= KeyFlagCertify
693
+		}
694
+		if sig.FlagSign {
695
+			flags |= KeyFlagSign
696
+		}
697
+		if sig.FlagEncryptCommunications {
698
+			flags |= KeyFlagEncryptCommunications
699
+		}
700
+		if sig.FlagEncryptStorage {
701
+			flags |= KeyFlagEncryptStorage
702
+		}
703
+		subpackets = append(subpackets, outputSubpacket{true, keyFlagsSubpacket, false, []byte{flags}})
704
+	}
705
+
706
+	// The following subpackets may only appear in self-signatures
707
+
708
+	if sig.KeyLifetimeSecs != nil && *sig.KeyLifetimeSecs != 0 {
709
+		keyLifetime := make([]byte, 4)
710
+		binary.BigEndian.PutUint32(keyLifetime, *sig.KeyLifetimeSecs)
711
+		subpackets = append(subpackets, outputSubpacket{true, keyExpirationSubpacket, true, keyLifetime})
712
+	}
713
+
714
+	if sig.IsPrimaryId != nil && *sig.IsPrimaryId {
715
+		subpackets = append(subpackets, outputSubpacket{true, primaryUserIdSubpacket, false, []byte{1}})
716
+	}
717
+
718
+	if len(sig.PreferredSymmetric) > 0 {
719
+		subpackets = append(subpackets, outputSubpacket{true, prefSymmetricAlgosSubpacket, false, sig.PreferredSymmetric})
720
+	}
721
+
722
+	if len(sig.PreferredHash) > 0 {
723
+		subpackets = append(subpackets, outputSubpacket{true, prefHashAlgosSubpacket, false, sig.PreferredHash})
724
+	}
725
+
726
+	if len(sig.PreferredCompression) > 0 {
727
+		subpackets = append(subpackets, outputSubpacket{true, prefCompressionSubpacket, false, sig.PreferredCompression})
728
+	}
729
+
730
+	return
731
+}

+ 78
- 0
vendor/src/golang.org/x/crypto/openpgp/packet/signature_test.go 查看文件

@@ -0,0 +1,78 @@
1
+// Copyright 2011 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
+
5
+package packet
6
+
7
+import (
8
+	"bytes"
9
+	"crypto"
10
+	"encoding/hex"
11
+	"testing"
12
+)
13
+
14
+func TestSignatureRead(t *testing.T) {
15
+	packet, err := Read(readerFromHex(signatureDataHex))
16
+	if err != nil {
17
+		t.Error(err)
18
+		return
19
+	}
20
+	sig, ok := packet.(*Signature)
21
+	if !ok || sig.SigType != SigTypeBinary || sig.PubKeyAlgo != PubKeyAlgoRSA || sig.Hash != crypto.SHA1 {
22
+		t.Errorf("failed to parse, got: %#v", packet)
23
+	}
24
+}
25
+
26
+func TestSignatureReserialize(t *testing.T) {
27
+	packet, _ := Read(readerFromHex(signatureDataHex))
28
+	sig := packet.(*Signature)
29
+	out := new(bytes.Buffer)
30
+	err := sig.Serialize(out)
31
+	if err != nil {
32
+		t.Errorf("error reserializing: %s", err)
33
+		return
34
+	}
35
+
36
+	expected, _ := hex.DecodeString(signatureDataHex)
37
+	if !bytes.Equal(expected, out.Bytes()) {
38
+		t.Errorf("output doesn't match input (got vs expected):\n%s\n%s", hex.Dump(out.Bytes()), hex.Dump(expected))
39
+	}
40
+}
41
+
42
+func TestSignUserId(t *testing.T) {
43
+	sig := &Signature{
44
+		SigType:    SigTypeGenericCert,
45
+		PubKeyAlgo: PubKeyAlgoRSA,
46
+		Hash:       0, // invalid hash function
47
+	}
48
+
49
+	packet, err := Read(readerFromHex(rsaPkDataHex))
50
+	if err != nil {
51
+		t.Fatalf("failed to deserialize public key: %v", err)
52
+	}
53
+	pubKey := packet.(*PublicKey)
54
+
55
+	packet, err = Read(readerFromHex(privKeyRSAHex))
56
+	if err != nil {
57
+		t.Fatalf("failed to deserialize private key: %v", err)
58
+	}
59
+	privKey := packet.(*PrivateKey)
60
+
61
+	err = sig.SignUserId("", pubKey, privKey, nil)
62
+	if err == nil {
63
+		t.Errorf("did not receive an error when expected")
64
+	}
65
+
66
+	sig.Hash = crypto.SHA256
67
+	err = privKey.Decrypt([]byte("testing"))
68
+	if err != nil {
69
+		t.Fatalf("failed to decrypt private key: %v", err)
70
+	}
71
+
72
+	err = sig.SignUserId("", pubKey, privKey, nil)
73
+	if err != nil {
74
+		t.Errorf("failed to sign user id: %v", err)
75
+	}
76
+}
77
+
78
+const signatureDataHex = "c2c05c04000102000605024cb45112000a0910ab105c91af38fb158f8d07ff5596ea368c5efe015bed6e78348c0f033c931d5f2ce5db54ce7f2a7e4b4ad64db758d65a7a71773edeab7ba2a9e0908e6a94a1175edd86c1d843279f045b021a6971a72702fcbd650efc393c5474d5b59a15f96d2eaad4c4c426797e0dcca2803ef41c6ff234d403eec38f31d610c344c06f2401c262f0993b2e66cad8a81ebc4322c723e0d4ba09fe917e8777658307ad8329adacba821420741009dfe87f007759f0982275d028a392c6ed983a0d846f890b36148c7358bdb8a516007fac760261ecd06076813831a36d0459075d1befa245ae7f7fb103d92ca759e9498fe60ef8078a39a3beda510deea251ea9f0a7f0df6ef42060f20780360686f3e400e"

+ 146
- 0
vendor/src/golang.org/x/crypto/openpgp/packet/signature_v3.go 查看文件

@@ -0,0 +1,146 @@
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
+
5
+package packet
6
+
7
+import (
8
+	"crypto"
9
+	"encoding/binary"
10
+	"fmt"
11
+	"io"
12
+	"strconv"
13
+	"time"
14
+
15
+	"golang.org/x/crypto/openpgp/errors"
16
+	"golang.org/x/crypto/openpgp/s2k"
17
+)
18
+
19
+// SignatureV3 represents older version 3 signatures. These signatures are less secure
20
+// than version 4 and should not be used to create new signatures. They are included
21
+// here for backwards compatibility to read and validate with older key material.
22
+// See RFC 4880, section 5.2.2.
23
+type SignatureV3 struct {
24
+	SigType      SignatureType
25
+	CreationTime time.Time
26
+	IssuerKeyId  uint64
27
+	PubKeyAlgo   PublicKeyAlgorithm
28
+	Hash         crypto.Hash
29
+	HashTag      [2]byte
30
+
31
+	RSASignature     parsedMPI
32
+	DSASigR, DSASigS parsedMPI
33
+}
34
+
35
+func (sig *SignatureV3) parse(r io.Reader) (err error) {
36
+	// RFC 4880, section 5.2.2
37
+	var buf [8]byte
38
+	if _, err = readFull(r, buf[:1]); err != nil {
39
+		return
40
+	}
41
+	if buf[0] < 2 || buf[0] > 3 {
42
+		err = errors.UnsupportedError("signature packet version " + strconv.Itoa(int(buf[0])))
43
+		return
44
+	}
45
+	if _, err = readFull(r, buf[:1]); err != nil {
46
+		return
47
+	}
48
+	if buf[0] != 5 {
49
+		err = errors.UnsupportedError(
50
+			"invalid hashed material length " + strconv.Itoa(int(buf[0])))
51
+		return
52
+	}
53
+
54
+	// Read hashed material: signature type + creation time
55
+	if _, err = readFull(r, buf[:5]); err != nil {
56
+		return
57
+	}
58
+	sig.SigType = SignatureType(buf[0])
59
+	t := binary.BigEndian.Uint32(buf[1:5])
60
+	sig.CreationTime = time.Unix(int64(t), 0)
61
+
62
+	// Eight-octet Key ID of signer.
63
+	if _, err = readFull(r, buf[:8]); err != nil {
64
+		return
65
+	}
66
+	sig.IssuerKeyId = binary.BigEndian.Uint64(buf[:])
67
+
68
+	// Public-key and hash algorithm
69
+	if _, err = readFull(r, buf[:2]); err != nil {
70
+		return
71
+	}
72
+	sig.PubKeyAlgo = PublicKeyAlgorithm(buf[0])
73
+	switch sig.PubKeyAlgo {
74
+	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoDSA:
75
+	default:
76
+		err = errors.UnsupportedError("public key algorithm " + strconv.Itoa(int(sig.PubKeyAlgo)))
77
+		return
78
+	}
79
+	var ok bool
80
+	if sig.Hash, ok = s2k.HashIdToHash(buf[1]); !ok {
81
+		return errors.UnsupportedError("hash function " + strconv.Itoa(int(buf[2])))
82
+	}
83
+
84
+	// Two-octet field holding left 16 bits of signed hash value.
85
+	if _, err = readFull(r, sig.HashTag[:2]); err != nil {
86
+		return
87
+	}
88
+
89
+	switch sig.PubKeyAlgo {
90
+	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
91
+		sig.RSASignature.bytes, sig.RSASignature.bitLength, err = readMPI(r)
92
+	case PubKeyAlgoDSA:
93
+		if sig.DSASigR.bytes, sig.DSASigR.bitLength, err = readMPI(r); err != nil {
94
+			return
95
+		}
96
+		sig.DSASigS.bytes, sig.DSASigS.bitLength, err = readMPI(r)
97
+	default:
98
+		panic("unreachable")
99
+	}
100
+	return
101
+}
102
+
103
+// Serialize marshals sig to w. Sign, SignUserId or SignKey must have been
104
+// called first.
105
+func (sig *SignatureV3) Serialize(w io.Writer) (err error) {
106
+	buf := make([]byte, 8)
107
+
108
+	// Write the sig type and creation time
109
+	buf[0] = byte(sig.SigType)
110
+	binary.BigEndian.PutUint32(buf[1:5], uint32(sig.CreationTime.Unix()))
111
+	if _, err = w.Write(buf[:5]); err != nil {
112
+		return
113
+	}
114
+
115
+	// Write the issuer long key ID
116
+	binary.BigEndian.PutUint64(buf[:8], sig.IssuerKeyId)
117
+	if _, err = w.Write(buf[:8]); err != nil {
118
+		return
119
+	}
120
+
121
+	// Write public key algorithm, hash ID, and hash value
122
+	buf[0] = byte(sig.PubKeyAlgo)
123
+	hashId, ok := s2k.HashToHashId(sig.Hash)
124
+	if !ok {
125
+		return errors.UnsupportedError(fmt.Sprintf("hash function %v", sig.Hash))
126
+	}
127
+	buf[1] = hashId
128
+	copy(buf[2:4], sig.HashTag[:])
129
+	if _, err = w.Write(buf[:4]); err != nil {
130
+		return
131
+	}
132
+
133
+	if sig.RSASignature.bytes == nil && sig.DSASigR.bytes == nil {
134
+		return errors.InvalidArgumentError("Signature: need to call Sign, SignUserId or SignKey before Serialize")
135
+	}
136
+
137
+	switch sig.PubKeyAlgo {
138
+	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
139
+		err = writeMPIs(w, sig.RSASignature)
140
+	case PubKeyAlgoDSA:
141
+		err = writeMPIs(w, sig.DSASigR, sig.DSASigS)
142
+	default:
143
+		panic("impossible")
144
+	}
145
+	return
146
+}

+ 92
- 0
vendor/src/golang.org/x/crypto/openpgp/packet/signature_v3_test.go 查看文件

@@ -0,0 +1,92 @@
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
+
5
+package packet
6
+
7
+import (
8
+	"bytes"
9
+	"crypto"
10
+	"encoding/hex"
11
+	"io"
12
+	"io/ioutil"
13
+	"testing"
14
+
15
+	"golang.org/x/crypto/openpgp/armor"
16
+)
17
+
18
+func TestSignatureV3Read(t *testing.T) {
19
+	r := v3KeyReader(t)
20
+	Read(r)                // Skip public key
21
+	Read(r)                // Skip uid
22
+	packet, err := Read(r) // Signature
23
+	if err != nil {
24
+		t.Error(err)
25
+		return
26
+	}
27
+	sig, ok := packet.(*SignatureV3)
28
+	if !ok || sig.SigType != SigTypeGenericCert || sig.PubKeyAlgo != PubKeyAlgoRSA || sig.Hash != crypto.MD5 {
29
+		t.Errorf("failed to parse, got: %#v", packet)
30
+	}
31
+}
32
+
33
+func TestSignatureV3Reserialize(t *testing.T) {
34
+	r := v3KeyReader(t)
35
+	Read(r) // Skip public key
36
+	Read(r) // Skip uid
37
+	packet, err := Read(r)
38
+	if err != nil {
39
+		t.Error(err)
40
+		return
41
+	}
42
+	sig := packet.(*SignatureV3)
43
+	out := new(bytes.Buffer)
44
+	if err = sig.Serialize(out); err != nil {
45
+		t.Errorf("error reserializing: %s", err)
46
+		return
47
+	}
48
+	expected, err := ioutil.ReadAll(v3KeyReader(t))
49
+	if err != nil {
50
+		t.Error(err)
51
+		return
52
+	}
53
+	expected = expected[4+141+4+39:] // See pgpdump offsets below, this is where the sig starts
54
+	if !bytes.Equal(expected, out.Bytes()) {
55
+		t.Errorf("output doesn't match input (got vs expected):\n%s\n%s", hex.Dump(out.Bytes()), hex.Dump(expected))
56
+	}
57
+}
58
+
59
+func v3KeyReader(t *testing.T) io.Reader {
60
+	armorBlock, err := armor.Decode(bytes.NewBufferString(keySigV3Armor))
61
+	if err != nil {
62
+		t.Fatalf("armor Decode failed: %v", err)
63
+	}
64
+	return armorBlock.Body
65
+}
66
+
67
+// keySigV3Armor is some V3 public key I found in an SKS dump.
68
+// Old: Public Key Packet(tag 6)(141 bytes)
69
+//      Ver 4 - new
70
+//      Public key creation time - Fri Sep 16 17:13:54 CDT 1994
71
+//      Pub alg - unknown(pub 0)
72
+//      Unknown public key(pub 0)
73
+// Old: User ID Packet(tag 13)(39 bytes)
74
+//      User ID - Armin M. Warda <warda@nephilim.ruhr.de>
75
+// Old: Signature Packet(tag 2)(149 bytes)
76
+//      Ver 4 - new
77
+//      Sig type - unknown(05)
78
+//      Pub alg - ElGamal Encrypt-Only(pub 16)
79
+//      Hash alg - unknown(hash 46)
80
+//      Hashed Sub: unknown(sub 81, critical)(1988 bytes)
81
+const keySigV3Armor = `-----BEGIN PGP PUBLIC KEY BLOCK-----
82
+Version: SKS 1.0.10
83
+
84
+mI0CLnoYogAAAQQA1qwA2SuJwfQ5bCQ6u5t20ulnOtY0gykf7YjiK4LiVeRBwHjGq7v30tGV
85
+5Qti7qqRW4Ww7CDCJc4sZMFnystucR2vLkXaSoNWoFm4Fg47NiisDdhDezHwbVPW6OpCFNSi
86
+ZAamtj4QAUBu8j4LswafrJqZqR9336/V3g8Yil2l48kABRG0J0FybWluIE0uIFdhcmRhIDx3
87
+YXJkYUBuZXBoaWxpbS5ydWhyLmRlPoiVAgUQLok2xwXR6zmeWEiZAQE/DgP/WgxPQh40/Po4
88
+gSkWZCDAjNdph7zexvAb0CcUWahcwiBIgg3U5ErCx9I5CNVA9U+s8bNrDZwgSIeBzp3KhWUx
89
+524uhGgm6ZUTOAIKA6CbV6pfqoLpJnRYvXYQU5mIWsNa99wcu2qu18OeEDnztb7aLA6Ra9OF
90
+YFCbq4EjXRoOrYM=
91
+=LPjs
92
+-----END PGP PUBLIC KEY BLOCK-----`

+ 155
- 0
vendor/src/golang.org/x/crypto/openpgp/packet/symmetric_key_encrypted.go 查看文件

@@ -0,0 +1,155 @@
1
+// Copyright 2011 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
+
5
+package packet
6
+
7
+import (
8
+	"bytes"
9
+	"crypto/cipher"
10
+	"io"
11
+	"strconv"
12
+
13
+	"golang.org/x/crypto/openpgp/errors"
14
+	"golang.org/x/crypto/openpgp/s2k"
15
+)
16
+
17
+// This is the largest session key that we'll support. Since no 512-bit cipher
18
+// has even been seriously used, this is comfortably large.
19
+const maxSessionKeySizeInBytes = 64
20
+
21
+// SymmetricKeyEncrypted represents a passphrase protected session key. See RFC
22
+// 4880, section 5.3.
23
+type SymmetricKeyEncrypted struct {
24
+	CipherFunc   CipherFunction
25
+	s2k          func(out, in []byte)
26
+	encryptedKey []byte
27
+}
28
+
29
+const symmetricKeyEncryptedVersion = 4
30
+
31
+func (ske *SymmetricKeyEncrypted) parse(r io.Reader) error {
32
+	// RFC 4880, section 5.3.
33
+	var buf [2]byte
34
+	if _, err := readFull(r, buf[:]); err != nil {
35
+		return err
36
+	}
37
+	if buf[0] != symmetricKeyEncryptedVersion {
38
+		return errors.UnsupportedError("SymmetricKeyEncrypted version")
39
+	}
40
+	ske.CipherFunc = CipherFunction(buf[1])
41
+
42
+	if ske.CipherFunc.KeySize() == 0 {
43
+		return errors.UnsupportedError("unknown cipher: " + strconv.Itoa(int(buf[1])))
44
+	}
45
+
46
+	var err error
47
+	ske.s2k, err = s2k.Parse(r)
48
+	if err != nil {
49
+		return err
50
+	}
51
+
52
+	encryptedKey := make([]byte, maxSessionKeySizeInBytes)
53
+	// The session key may follow. We just have to try and read to find
54
+	// out. If it exists then we limit it to maxSessionKeySizeInBytes.
55
+	n, err := readFull(r, encryptedKey)
56
+	if err != nil && err != io.ErrUnexpectedEOF {
57
+		return err
58
+	}
59
+
60
+	if n != 0 {
61
+		if n == maxSessionKeySizeInBytes {
62
+			return errors.UnsupportedError("oversized encrypted session key")
63
+		}
64
+		ske.encryptedKey = encryptedKey[:n]
65
+	}
66
+
67
+	return nil
68
+}
69
+
70
+// Decrypt attempts to decrypt an encrypted session key and returns the key and
71
+// the cipher to use when decrypting a subsequent Symmetrically Encrypted Data
72
+// packet.
73
+func (ske *SymmetricKeyEncrypted) Decrypt(passphrase []byte) ([]byte, CipherFunction, error) {
74
+	key := make([]byte, ske.CipherFunc.KeySize())
75
+	ske.s2k(key, passphrase)
76
+
77
+	if len(ske.encryptedKey) == 0 {
78
+		return key, ske.CipherFunc, nil
79
+	}
80
+
81
+	// the IV is all zeros
82
+	iv := make([]byte, ske.CipherFunc.blockSize())
83
+	c := cipher.NewCFBDecrypter(ske.CipherFunc.new(key), iv)
84
+	plaintextKey := make([]byte, len(ske.encryptedKey))
85
+	c.XORKeyStream(plaintextKey, ske.encryptedKey)
86
+	cipherFunc := CipherFunction(plaintextKey[0])
87
+	if cipherFunc.blockSize() == 0 {
88
+		return nil, ske.CipherFunc, errors.UnsupportedError("unknown cipher: " + strconv.Itoa(int(cipherFunc)))
89
+	}
90
+	plaintextKey = plaintextKey[1:]
91
+	if l, cipherKeySize := len(plaintextKey), cipherFunc.KeySize(); l != cipherFunc.KeySize() {
92
+		return nil, cipherFunc, errors.StructuralError("length of decrypted key (" + strconv.Itoa(l) + ") " +
93
+			"not equal to cipher keysize (" + strconv.Itoa(cipherKeySize) + ")")
94
+	}
95
+	return plaintextKey, cipherFunc, nil
96
+}
97
+
98
+// SerializeSymmetricKeyEncrypted serializes a symmetric key packet to w. The
99
+// packet contains a random session key, encrypted by a key derived from the
100
+// given passphrase. The session key is returned and must be passed to
101
+// SerializeSymmetricallyEncrypted.
102
+// If config is nil, sensible defaults will be used.
103
+func SerializeSymmetricKeyEncrypted(w io.Writer, passphrase []byte, config *Config) (key []byte, err error) {
104
+	cipherFunc := config.Cipher()
105
+	keySize := cipherFunc.KeySize()
106
+	if keySize == 0 {
107
+		return nil, errors.UnsupportedError("unknown cipher: " + strconv.Itoa(int(cipherFunc)))
108
+	}
109
+
110
+	s2kBuf := new(bytes.Buffer)
111
+	keyEncryptingKey := make([]byte, keySize)
112
+	// s2k.Serialize salts and stretches the passphrase, and writes the
113
+	// resulting key to keyEncryptingKey and the s2k descriptor to s2kBuf.
114
+	err = s2k.Serialize(s2kBuf, keyEncryptingKey, config.Random(), passphrase, &s2k.Config{Hash: config.Hash(), S2KCount: config.PasswordHashIterations()})
115
+	if err != nil {
116
+		return
117
+	}
118
+	s2kBytes := s2kBuf.Bytes()
119
+
120
+	packetLength := 2 /* header */ + len(s2kBytes) + 1 /* cipher type */ + keySize
121
+	err = serializeHeader(w, packetTypeSymmetricKeyEncrypted, packetLength)
122
+	if err != nil {
123
+		return
124
+	}
125
+
126
+	var buf [2]byte
127
+	buf[0] = symmetricKeyEncryptedVersion
128
+	buf[1] = byte(cipherFunc)
129
+	_, err = w.Write(buf[:])
130
+	if err != nil {
131
+		return
132
+	}
133
+	_, err = w.Write(s2kBytes)
134
+	if err != nil {
135
+		return
136
+	}
137
+
138
+	sessionKey := make([]byte, keySize)
139
+	_, err = io.ReadFull(config.Random(), sessionKey)
140
+	if err != nil {
141
+		return
142
+	}
143
+	iv := make([]byte, cipherFunc.blockSize())
144
+	c := cipher.NewCFBEncrypter(cipherFunc.new(keyEncryptingKey), iv)
145
+	encryptedCipherAndKey := make([]byte, keySize+1)
146
+	c.XORKeyStream(encryptedCipherAndKey, buf[1:])
147
+	c.XORKeyStream(encryptedCipherAndKey[1:], sessionKey)
148
+	_, err = w.Write(encryptedCipherAndKey)
149
+	if err != nil {
150
+		return
151
+	}
152
+
153
+	key = sessionKey
154
+	return
155
+}

+ 117
- 0
vendor/src/golang.org/x/crypto/openpgp/packet/symmetric_key_encrypted_test.go 查看文件

@@ -0,0 +1,117 @@
1
+// Copyright 2011 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
+
5
+package packet
6
+
7
+import (
8
+	"bytes"
9
+	"encoding/hex"
10
+	"io"
11
+	"io/ioutil"
12
+	"testing"
13
+)
14
+
15
+func TestSymmetricKeyEncrypted(t *testing.T) {
16
+	buf := readerFromHex(symmetricallyEncryptedHex)
17
+	packet, err := Read(buf)
18
+	if err != nil {
19
+		t.Errorf("failed to read SymmetricKeyEncrypted: %s", err)
20
+		return
21
+	}
22
+	ske, ok := packet.(*SymmetricKeyEncrypted)
23
+	if !ok {
24
+		t.Error("didn't find SymmetricKeyEncrypted packet")
25
+		return
26
+	}
27
+	key, cipherFunc, err := ske.Decrypt([]byte("password"))
28
+	if err != nil {
29
+		t.Error(err)
30
+		return
31
+	}
32
+
33
+	packet, err = Read(buf)
34
+	if err != nil {
35
+		t.Errorf("failed to read SymmetricallyEncrypted: %s", err)
36
+		return
37
+	}
38
+	se, ok := packet.(*SymmetricallyEncrypted)
39
+	if !ok {
40
+		t.Error("didn't find SymmetricallyEncrypted packet")
41
+		return
42
+	}
43
+	r, err := se.Decrypt(cipherFunc, key)
44
+	if err != nil {
45
+		t.Error(err)
46
+		return
47
+	}
48
+
49
+	contents, err := ioutil.ReadAll(r)
50
+	if err != nil && err != io.EOF {
51
+		t.Error(err)
52
+		return
53
+	}
54
+
55
+	expectedContents, _ := hex.DecodeString(symmetricallyEncryptedContentsHex)
56
+	if !bytes.Equal(expectedContents, contents) {
57
+		t.Errorf("bad contents got:%x want:%x", contents, expectedContents)
58
+	}
59
+}
60
+
61
+const symmetricallyEncryptedHex = "8c0d04030302371a0b38d884f02060c91cf97c9973b8e58e028e9501708ccfe618fb92afef7fa2d80ddadd93cf"
62
+const symmetricallyEncryptedContentsHex = "cb1062004d14c4df636f6e74656e74732e0a"
63
+
64
+func TestSerializeSymmetricKeyEncryptedCiphers(t *testing.T) {
65
+	tests := [...]struct {
66
+		cipherFunc CipherFunction
67
+		name       string
68
+	}{
69
+		{Cipher3DES, "Cipher3DES"},
70
+		{CipherCAST5, "CipherCAST5"},
71
+		{CipherAES128, "CipherAES128"},
72
+		{CipherAES192, "CipherAES192"},
73
+		{CipherAES256, "CipherAES256"},
74
+	}
75
+
76
+	for _, test := range tests {
77
+		var buf bytes.Buffer
78
+		passphrase := []byte("testing")
79
+		config := &Config{
80
+			DefaultCipher: test.cipherFunc,
81
+		}
82
+
83
+		key, err := SerializeSymmetricKeyEncrypted(&buf, passphrase, config)
84
+		if err != nil {
85
+			t.Errorf("cipher(%s) failed to serialize: %s", test.name, err)
86
+			continue
87
+		}
88
+
89
+		p, err := Read(&buf)
90
+		if err != nil {
91
+			t.Errorf("cipher(%s) failed to reparse: %s", test.name, err)
92
+			continue
93
+		}
94
+
95
+		ske, ok := p.(*SymmetricKeyEncrypted)
96
+		if !ok {
97
+			t.Errorf("cipher(%s) parsed a different packet type: %#v", test.name, p)
98
+			continue
99
+		}
100
+
101
+		if ske.CipherFunc != config.DefaultCipher {
102
+			t.Errorf("cipher(%s) SKE cipher function is %d (expected %d)", test.name, ske.CipherFunc, config.DefaultCipher)
103
+		}
104
+		parsedKey, parsedCipherFunc, err := ske.Decrypt(passphrase)
105
+		if err != nil {
106
+			t.Errorf("cipher(%s) failed to decrypt reparsed SKE: %s", test.name, err)
107
+			continue
108
+		}
109
+		if !bytes.Equal(key, parsedKey) {
110
+			t.Errorf("cipher(%s) keys don't match after Decrypt: %x (original) vs %x (parsed)", test.name, key, parsedKey)
111
+		}
112
+		if parsedCipherFunc != test.cipherFunc {
113
+			t.Errorf("cipher(%s) cipher function doesn't match after Decrypt: %d (original) vs %d (parsed)",
114
+				test.name, test.cipherFunc, parsedCipherFunc)
115
+		}
116
+	}
117
+}

+ 290
- 0
vendor/src/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted.go 查看文件

@@ -0,0 +1,290 @@
1
+// Copyright 2011 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
+
5
+package packet
6
+
7
+import (
8
+	"crypto/cipher"
9
+	"crypto/sha1"
10
+	"crypto/subtle"
11
+	"golang.org/x/crypto/openpgp/errors"
12
+	"hash"
13
+	"io"
14
+	"strconv"
15
+)
16
+
17
+// SymmetricallyEncrypted represents a symmetrically encrypted byte string. The
18
+// encrypted contents will consist of more OpenPGP packets. See RFC 4880,
19
+// sections 5.7 and 5.13.
20
+type SymmetricallyEncrypted struct {
21
+	MDC      bool // true iff this is a type 18 packet and thus has an embedded MAC.
22
+	contents io.Reader
23
+	prefix   []byte
24
+}
25
+
26
+const symmetricallyEncryptedVersion = 1
27
+
28
+func (se *SymmetricallyEncrypted) parse(r io.Reader) error {
29
+	if se.MDC {
30
+		// See RFC 4880, section 5.13.
31
+		var buf [1]byte
32
+		_, err := readFull(r, buf[:])
33
+		if err != nil {
34
+			return err
35
+		}
36
+		if buf[0] != symmetricallyEncryptedVersion {
37
+			return errors.UnsupportedError("unknown SymmetricallyEncrypted version")
38
+		}
39
+	}
40
+	se.contents = r
41
+	return nil
42
+}
43
+
44
+// Decrypt returns a ReadCloser, from which the decrypted contents of the
45
+// packet can be read. An incorrect key can, with high probability, be detected
46
+// immediately and this will result in a KeyIncorrect error being returned.
47
+func (se *SymmetricallyEncrypted) Decrypt(c CipherFunction, key []byte) (io.ReadCloser, error) {
48
+	keySize := c.KeySize()
49
+	if keySize == 0 {
50
+		return nil, errors.UnsupportedError("unknown cipher: " + strconv.Itoa(int(c)))
51
+	}
52
+	if len(key) != keySize {
53
+		return nil, errors.InvalidArgumentError("SymmetricallyEncrypted: incorrect key length")
54
+	}
55
+
56
+	if se.prefix == nil {
57
+		se.prefix = make([]byte, c.blockSize()+2)
58
+		_, err := readFull(se.contents, se.prefix)
59
+		if err != nil {
60
+			return nil, err
61
+		}
62
+	} else if len(se.prefix) != c.blockSize()+2 {
63
+		return nil, errors.InvalidArgumentError("can't try ciphers with different block lengths")
64
+	}
65
+
66
+	ocfbResync := OCFBResync
67
+	if se.MDC {
68
+		// MDC packets use a different form of OCFB mode.
69
+		ocfbResync = OCFBNoResync
70
+	}
71
+
72
+	s := NewOCFBDecrypter(c.new(key), se.prefix, ocfbResync)
73
+	if s == nil {
74
+		return nil, errors.ErrKeyIncorrect
75
+	}
76
+
77
+	plaintext := cipher.StreamReader{S: s, R: se.contents}
78
+
79
+	if se.MDC {
80
+		// MDC packets have an embedded hash that we need to check.
81
+		h := sha1.New()
82
+		h.Write(se.prefix)
83
+		return &seMDCReader{in: plaintext, h: h}, nil
84
+	}
85
+
86
+	// Otherwise, we just need to wrap plaintext so that it's a valid ReadCloser.
87
+	return seReader{plaintext}, nil
88
+}
89
+
90
+// seReader wraps an io.Reader with a no-op Close method.
91
+type seReader struct {
92
+	in io.Reader
93
+}
94
+
95
+func (ser seReader) Read(buf []byte) (int, error) {
96
+	return ser.in.Read(buf)
97
+}
98
+
99
+func (ser seReader) Close() error {
100
+	return nil
101
+}
102
+
103
+const mdcTrailerSize = 1 /* tag byte */ + 1 /* length byte */ + sha1.Size
104
+
105
+// An seMDCReader wraps an io.Reader, maintains a running hash and keeps hold
106
+// of the most recent 22 bytes (mdcTrailerSize). Upon EOF, those bytes form an
107
+// MDC packet containing a hash of the previous contents which is checked
108
+// against the running hash. See RFC 4880, section 5.13.
109
+type seMDCReader struct {
110
+	in          io.Reader
111
+	h           hash.Hash
112
+	trailer     [mdcTrailerSize]byte
113
+	scratch     [mdcTrailerSize]byte
114
+	trailerUsed int
115
+	error       bool
116
+	eof         bool
117
+}
118
+
119
+func (ser *seMDCReader) Read(buf []byte) (n int, err error) {
120
+	if ser.error {
121
+		err = io.ErrUnexpectedEOF
122
+		return
123
+	}
124
+	if ser.eof {
125
+		err = io.EOF
126
+		return
127
+	}
128
+
129
+	// If we haven't yet filled the trailer buffer then we must do that
130
+	// first.
131
+	for ser.trailerUsed < mdcTrailerSize {
132
+		n, err = ser.in.Read(ser.trailer[ser.trailerUsed:])
133
+		ser.trailerUsed += n
134
+		if err == io.EOF {
135
+			if ser.trailerUsed != mdcTrailerSize {
136
+				n = 0
137
+				err = io.ErrUnexpectedEOF
138
+				ser.error = true
139
+				return
140
+			}
141
+			ser.eof = true
142
+			n = 0
143
+			return
144
+		}
145
+
146
+		if err != nil {
147
+			n = 0
148
+			return
149
+		}
150
+	}
151
+
152
+	// If it's a short read then we read into a temporary buffer and shift
153
+	// the data into the caller's buffer.
154
+	if len(buf) <= mdcTrailerSize {
155
+		n, err = readFull(ser.in, ser.scratch[:len(buf)])
156
+		copy(buf, ser.trailer[:n])
157
+		ser.h.Write(buf[:n])
158
+		copy(ser.trailer[:], ser.trailer[n:])
159
+		copy(ser.trailer[mdcTrailerSize-n:], ser.scratch[:])
160
+		if n < len(buf) {
161
+			ser.eof = true
162
+			err = io.EOF
163
+		}
164
+		return
165
+	}
166
+
167
+	n, err = ser.in.Read(buf[mdcTrailerSize:])
168
+	copy(buf, ser.trailer[:])
169
+	ser.h.Write(buf[:n])
170
+	copy(ser.trailer[:], buf[n:])
171
+
172
+	if err == io.EOF {
173
+		ser.eof = true
174
+	}
175
+	return
176
+}
177
+
178
+// This is a new-format packet tag byte for a type 19 (MDC) packet.
179
+const mdcPacketTagByte = byte(0x80) | 0x40 | 19
180
+
181
+func (ser *seMDCReader) Close() error {
182
+	if ser.error {
183
+		return errors.SignatureError("error during reading")
184
+	}
185
+
186
+	for !ser.eof {
187
+		// We haven't seen EOF so we need to read to the end
188
+		var buf [1024]byte
189
+		_, err := ser.Read(buf[:])
190
+		if err == io.EOF {
191
+			break
192
+		}
193
+		if err != nil {
194
+			return errors.SignatureError("error during reading")
195
+		}
196
+	}
197
+
198
+	if ser.trailer[0] != mdcPacketTagByte || ser.trailer[1] != sha1.Size {
199
+		return errors.SignatureError("MDC packet not found")
200
+	}
201
+	ser.h.Write(ser.trailer[:2])
202
+
203
+	final := ser.h.Sum(nil)
204
+	if subtle.ConstantTimeCompare(final, ser.trailer[2:]) != 1 {
205
+		return errors.SignatureError("hash mismatch")
206
+	}
207
+	return nil
208
+}
209
+
210
+// An seMDCWriter writes through to an io.WriteCloser while maintains a running
211
+// hash of the data written. On close, it emits an MDC packet containing the
212
+// running hash.
213
+type seMDCWriter struct {
214
+	w io.WriteCloser
215
+	h hash.Hash
216
+}
217
+
218
+func (w *seMDCWriter) Write(buf []byte) (n int, err error) {
219
+	w.h.Write(buf)
220
+	return w.w.Write(buf)
221
+}
222
+
223
+func (w *seMDCWriter) Close() (err error) {
224
+	var buf [mdcTrailerSize]byte
225
+
226
+	buf[0] = mdcPacketTagByte
227
+	buf[1] = sha1.Size
228
+	w.h.Write(buf[:2])
229
+	digest := w.h.Sum(nil)
230
+	copy(buf[2:], digest)
231
+
232
+	_, err = w.w.Write(buf[:])
233
+	if err != nil {
234
+		return
235
+	}
236
+	return w.w.Close()
237
+}
238
+
239
+// noOpCloser is like an ioutil.NopCloser, but for an io.Writer.
240
+type noOpCloser struct {
241
+	w io.Writer
242
+}
243
+
244
+func (c noOpCloser) Write(data []byte) (n int, err error) {
245
+	return c.w.Write(data)
246
+}
247
+
248
+func (c noOpCloser) Close() error {
249
+	return nil
250
+}
251
+
252
+// SerializeSymmetricallyEncrypted serializes a symmetrically encrypted packet
253
+// to w and returns a WriteCloser to which the to-be-encrypted packets can be
254
+// written.
255
+// If config is nil, sensible defaults will be used.
256
+func SerializeSymmetricallyEncrypted(w io.Writer, c CipherFunction, key []byte, config *Config) (contents io.WriteCloser, err error) {
257
+	if c.KeySize() != len(key) {
258
+		return nil, errors.InvalidArgumentError("SymmetricallyEncrypted.Serialize: bad key length")
259
+	}
260
+	writeCloser := noOpCloser{w}
261
+	ciphertext, err := serializeStreamHeader(writeCloser, packetTypeSymmetricallyEncryptedMDC)
262
+	if err != nil {
263
+		return
264
+	}
265
+
266
+	_, err = ciphertext.Write([]byte{symmetricallyEncryptedVersion})
267
+	if err != nil {
268
+		return
269
+	}
270
+
271
+	block := c.new(key)
272
+	blockSize := block.BlockSize()
273
+	iv := make([]byte, blockSize)
274
+	_, err = config.Random().Read(iv)
275
+	if err != nil {
276
+		return
277
+	}
278
+	s, prefix := NewOCFBEncrypter(block, iv, OCFBNoResync)
279
+	_, err = ciphertext.Write(prefix)
280
+	if err != nil {
281
+		return
282
+	}
283
+	plaintext := cipher.StreamWriter{S: s, W: ciphertext}
284
+
285
+	h := sha1.New()
286
+	h.Write(iv)
287
+	h.Write(iv[blockSize-2:])
288
+	contents = &seMDCWriter{w: plaintext, h: h}
289
+	return
290
+}

+ 123
- 0
vendor/src/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted_test.go 查看文件

@@ -0,0 +1,123 @@
1
+// Copyright 2011 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
+
5
+package packet
6
+
7
+import (
8
+	"bytes"
9
+	"crypto/sha1"
10
+	"encoding/hex"
11
+	"golang.org/x/crypto/openpgp/errors"
12
+	"io"
13
+	"io/ioutil"
14
+	"testing"
15
+)
16
+
17
+// TestReader wraps a []byte and returns reads of a specific length.
18
+type testReader struct {
19
+	data   []byte
20
+	stride int
21
+}
22
+
23
+func (t *testReader) Read(buf []byte) (n int, err error) {
24
+	n = t.stride
25
+	if n > len(t.data) {
26
+		n = len(t.data)
27
+	}
28
+	if n > len(buf) {
29
+		n = len(buf)
30
+	}
31
+	copy(buf, t.data)
32
+	t.data = t.data[n:]
33
+	if len(t.data) == 0 {
34
+		err = io.EOF
35
+	}
36
+	return
37
+}
38
+
39
+func testMDCReader(t *testing.T) {
40
+	mdcPlaintext, _ := hex.DecodeString(mdcPlaintextHex)
41
+
42
+	for stride := 1; stride < len(mdcPlaintext)/2; stride++ {
43
+		r := &testReader{data: mdcPlaintext, stride: stride}
44
+		mdcReader := &seMDCReader{in: r, h: sha1.New()}
45
+		body, err := ioutil.ReadAll(mdcReader)
46
+		if err != nil {
47
+			t.Errorf("stride: %d, error: %s", stride, err)
48
+			continue
49
+		}
50
+		if !bytes.Equal(body, mdcPlaintext[:len(mdcPlaintext)-22]) {
51
+			t.Errorf("stride: %d: bad contents %x", stride, body)
52
+			continue
53
+		}
54
+
55
+		err = mdcReader.Close()
56
+		if err != nil {
57
+			t.Errorf("stride: %d, error on Close: %s", stride, err)
58
+		}
59
+	}
60
+
61
+	mdcPlaintext[15] ^= 80
62
+
63
+	r := &testReader{data: mdcPlaintext, stride: 2}
64
+	mdcReader := &seMDCReader{in: r, h: sha1.New()}
65
+	_, err := ioutil.ReadAll(mdcReader)
66
+	if err != nil {
67
+		t.Errorf("corruption test, error: %s", err)
68
+		return
69
+	}
70
+	err = mdcReader.Close()
71
+	if err == nil {
72
+		t.Error("corruption: no error")
73
+	} else if _, ok := err.(*errors.SignatureError); !ok {
74
+		t.Errorf("corruption: expected SignatureError, got: %s", err)
75
+	}
76
+}
77
+
78
+const mdcPlaintextHex = "a302789c3b2d93c4e0eb9aba22283539b3203335af44a134afb800c849cb4c4de10200aff40b45d31432c80cb384299a0655966d6939dfdeed1dddf980"
79
+
80
+func TestSerialize(t *testing.T) {
81
+	buf := bytes.NewBuffer(nil)
82
+	c := CipherAES128
83
+	key := make([]byte, c.KeySize())
84
+
85
+	w, err := SerializeSymmetricallyEncrypted(buf, c, key, nil)
86
+	if err != nil {
87
+		t.Errorf("error from SerializeSymmetricallyEncrypted: %s", err)
88
+		return
89
+	}
90
+
91
+	contents := []byte("hello world\n")
92
+
93
+	w.Write(contents)
94
+	w.Close()
95
+
96
+	p, err := Read(buf)
97
+	if err != nil {
98
+		t.Errorf("error from Read: %s", err)
99
+		return
100
+	}
101
+
102
+	se, ok := p.(*SymmetricallyEncrypted)
103
+	if !ok {
104
+		t.Errorf("didn't read a *SymmetricallyEncrypted")
105
+		return
106
+	}
107
+
108
+	r, err := se.Decrypt(c, key)
109
+	if err != nil {
110
+		t.Errorf("error from Decrypt: %s", err)
111
+		return
112
+	}
113
+
114
+	contentsCopy := bytes.NewBuffer(nil)
115
+	_, err = io.Copy(contentsCopy, r)
116
+	if err != nil {
117
+		t.Errorf("error from io.Copy: %s", err)
118
+		return
119
+	}
120
+	if !bytes.Equal(contentsCopy.Bytes(), contents) {
121
+		t.Errorf("contents not equal got: %x want: %x", contentsCopy.Bytes(), contents)
122
+	}
123
+}

+ 91
- 0
vendor/src/golang.org/x/crypto/openpgp/packet/userattribute.go 查看文件

@@ -0,0 +1,91 @@
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
+
5
+package packet
6
+
7
+import (
8
+	"bytes"
9
+	"image"
10
+	"image/jpeg"
11
+	"io"
12
+	"io/ioutil"
13
+)
14
+
15
+const UserAttrImageSubpacket = 1
16
+
17
+// UserAttribute is capable of storing other types of data about a user
18
+// beyond name, email and a text comment. In practice, user attributes are typically used
19
+// to store a signed thumbnail photo JPEG image of the user.
20
+// See RFC 4880, section 5.12.
21
+type UserAttribute struct {
22
+	Contents []*OpaqueSubpacket
23
+}
24
+
25
+// NewUserAttributePhoto creates a user attribute packet
26
+// containing the given images.
27
+func NewUserAttributePhoto(photos ...image.Image) (uat *UserAttribute, err error) {
28
+	uat = new(UserAttribute)
29
+	for _, photo := range photos {
30
+		var buf bytes.Buffer
31
+		// RFC 4880, Section 5.12.1.
32
+		data := []byte{
33
+			0x10, 0x00, // Little-endian image header length (16 bytes)
34
+			0x01,       // Image header version 1
35
+			0x01,       // JPEG
36
+			0, 0, 0, 0, // 12 reserved octets, must be all zero.
37
+			0, 0, 0, 0,
38
+			0, 0, 0, 0}
39
+		if _, err = buf.Write(data); err != nil {
40
+			return
41
+		}
42
+		if err = jpeg.Encode(&buf, photo, nil); err != nil {
43
+			return
44
+		}
45
+		uat.Contents = append(uat.Contents, &OpaqueSubpacket{
46
+			SubType:  UserAttrImageSubpacket,
47
+			Contents: buf.Bytes()})
48
+	}
49
+	return
50
+}
51
+
52
+// NewUserAttribute creates a new user attribute packet containing the given subpackets.
53
+func NewUserAttribute(contents ...*OpaqueSubpacket) *UserAttribute {
54
+	return &UserAttribute{Contents: contents}
55
+}
56
+
57
+func (uat *UserAttribute) parse(r io.Reader) (err error) {
58
+	// RFC 4880, section 5.13
59
+	b, err := ioutil.ReadAll(r)
60
+	if err != nil {
61
+		return
62
+	}
63
+	uat.Contents, err = OpaqueSubpackets(b)
64
+	return
65
+}
66
+
67
+// Serialize marshals the user attribute to w in the form of an OpenPGP packet, including
68
+// header.
69
+func (uat *UserAttribute) Serialize(w io.Writer) (err error) {
70
+	var buf bytes.Buffer
71
+	for _, sp := range uat.Contents {
72
+		sp.Serialize(&buf)
73
+	}
74
+	if err = serializeHeader(w, packetTypeUserAttribute, buf.Len()); err != nil {
75
+		return err
76
+	}
77
+	_, err = w.Write(buf.Bytes())
78
+	return
79
+}
80
+
81
+// ImageData returns zero or more byte slices, each containing
82
+// JPEG File Interchange Format (JFIF), for each photo in the
83
+// the user attribute packet.
84
+func (uat *UserAttribute) ImageData() (imageData [][]byte) {
85
+	for _, sp := range uat.Contents {
86
+		if sp.SubType == UserAttrImageSubpacket && len(sp.Contents) > 16 {
87
+			imageData = append(imageData, sp.Contents[16:])
88
+		}
89
+	}
90
+	return
91
+}

+ 109
- 0
vendor/src/golang.org/x/crypto/openpgp/packet/userattribute_test.go 查看文件

@@ -0,0 +1,109 @@
1
+// Copyright 2011 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
+
5
+package packet
6
+
7
+import (
8
+	"bytes"
9
+	"encoding/base64"
10
+	"image/color"
11
+	"image/jpeg"
12
+	"testing"
13
+)
14
+
15
+func TestParseUserAttribute(t *testing.T) {
16
+	r := base64.NewDecoder(base64.StdEncoding, bytes.NewBufferString(userAttributePacket))
17
+	for i := 0; i < 2; i++ {
18
+		p, err := Read(r)
19
+		if err != nil {
20
+			t.Fatal(err)
21
+		}
22
+		uat := p.(*UserAttribute)
23
+		imgs := uat.ImageData()
24
+		if len(imgs) != 1 {
25
+			t.Errorf("Unexpected number of images in user attribute packet: %d", len(imgs))
26
+		}
27
+		if len(imgs[0]) != 3395 {
28
+			t.Errorf("Unexpected JPEG image size: %d", len(imgs[0]))
29
+		}
30
+		img, err := jpeg.Decode(bytes.NewBuffer(imgs[0]))
31
+		if err != nil {
32
+			t.Errorf("Error decoding JPEG image: %v", err)
33
+		}
34
+		// A pixel in my right eye.
35
+		pixel := color.NRGBAModel.Convert(img.At(56, 36))
36
+		ref := color.NRGBA{R: 157, G: 128, B: 124, A: 255}
37
+		if pixel != ref {
38
+			t.Errorf("Unexpected pixel color: %v", pixel)
39
+		}
40
+		w := bytes.NewBuffer(nil)
41
+		err = uat.Serialize(w)
42
+		if err != nil {
43
+			t.Errorf("Error writing user attribute: %v", err)
44
+		}
45
+		r = bytes.NewBuffer(w.Bytes())
46
+	}
47
+}
48
+
49
+const userAttributePacket = `
50
+0cyWzJQBEAABAQAAAAAAAAAAAAAAAP/Y/+AAEEpGSUYAAQIAAAEAAQAA/9sAQwAFAwQEBAMFBAQE
51
+BQUFBgcMCAcHBwcPCgsJDBEPEhIRDxEQExYcFxMUGhUQERghGBocHR8fHxMXIiQiHiQcHh8e/9sA
52
+QwEFBQUHBgcOCAgOHhQRFB4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4e
53
+Hh4eHh4eHh4e/8AAEQgAZABkAwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYH
54
+CAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHw
55
+JDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6
56
+g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk
57
+5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIB
58
+AgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEX
59
+GBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKT
60
+lJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX2
61
+9/j5+v/aAAwDAQACEQMRAD8A5uGP06VehQ4pIox04q5EnHSvAep+hIIl4zVuMHGPWmRrUWtalaaN
62
+pU2oXsgSGJSxPr6ClvoitErs0Itqjc7BQOpPAFYmrfEnwjojtHNqaXEynBjtx5hH4jj9a8B8d+Od
63
+W8UXZjWR4LJT+7t0Jwfc+prnIdO1CWZEW2mZ3HyDactXXDB3V5s8evm1namj6r0H4weCLtxG+ova
64
+ueP30RA/MV6not1bX0Ed1ZzxzwyDKvGwZSPqK+Ff+ES8R8t/ZV2oHUmM10Hgbxp4m8BatEfNnWBH
65
+/eWshOxx9Kmpg4te49RUM1kn+8Wh9zQ4P1FaMC7l465rjPh14y0fxnoseoaXOpfaPOgJ+eI98j09
66
+67W19M15bi4uzPSqTU480WXkjZkAyAR61DPE6OCSOalWRRgZxjvTb598sfU4FBwx5uY4T4feIm8P
67
+TeJbAgc65NIM+8cX+FFeLfF3Vr3SfiNrMFrMypJMJcDPUqP8KK+kpVFyLU+ar037SXqX4hxVpMY7
68
+1UhPpVlT2rybKx9smWYz3NeH/EDVLzxt40j8O6bITaQybPlbKkjq39K9O8fasdH8IahfKxWQRFIy
69
+Ou9uB/OuE/Z/0y3j1d9TuyoZCMs5xjuea1pLli5nn46q240l13PcfhN8EvDNtpcEl/CklyVBLuMk
70
+mvU/Dfwo0BL/AO13FjEDD/qyV7Vn+CvGPg8zRpJrVm8ikLtEg6+1ew2dxZ3EQaJgysuQPasH7eXW
71
+1zzsbVhT92kk/PsYieEND+zlPs6c/wCyAPyryH4wfCPRtW0u6j+xRLOxLxSoADkDpXY+MPjJ4c0S
72
+9k082d3O8ZKkxw5XI96ytK+IGk+IpFjRpod+Qq3C7QT6A1E6NenaXbqRg6rlLlqS0fRnxjpd1r/w
73
+w8afa7GWRPKbZLGeBKmeVNfZngLxNaeKfDdprVjxHcLlkJ5Vh1H5185/tDad9h8XOsqAw3Cb0cjq
74
+CfX61P8AsveKf7L8T3fhe5nxa3g324YniQdh9R/KuivTdSmp9TXB1/Z1nRlsfU249QBx1pWfcwI7
75
+Cq6u2Ovamb9rYz16V5x7Psz5q/aJhZfibcupIElvE3H+7j+lFbXx9szP45jlUfeso8/99OKK9elL
76
+3EeNVopzZVharCtxVRGGMk02S5JyFOB69zWTieypnL/GksfB+0cr9oQt69awPhPpD69Y3Ky3DWth
77
+CWluGU4LAdq3vibGs/g68BJygVxjrwRW5+ztoRv/AAs8EeCZnO/J/hzz/Kumi4wp3kePjlOdZKPY
78
+ml8Mvo6WM9ppi7J0EkQYMzkb1X0wW+bJHGACa+ivg14huZPCkjXUO6SImIYOQAP6UQ2sGneHmiWF
79
+CYoSAAuM8etXfhBpMr+EZ3SSNRcMx6ZxWdes6ytBGSwkMNFuo7pnP614Ut9Zn1C4uLySKcwObGFA
80
+Qnm4+XcR71h+CfDHiKCQWuv2YWFtw+bBZQD8rcE8n2Ney+GbGGQSM6I7xvtI681rXdp8hKRRp6t3
81
+FYPE1VDlsY1nQjWdl+J8w/tOeDZZ/AMd/EGefTHyxxyYjwfyODXg3waRh8UtEcFh+8Jb8FNfZPxh
82
+Ak8J6nbPIsiyW7LnseK+Ofh99ptPHFnf2lu0y2twGcKuSEPB/Q1WHk50miq1o14TXU+xop+On61H
83
+NMC6Nis1LgsAcUTSt1APFcXJZn0EqmhyvxA037friTYziBV6f7Tf40Vr3k4aXLx5OMZIzRXZB2ik
84
+efJXbPHJJcnaD9aN2R1qoGO8/WkuLlIV+YjdjpXSonQ5lTxfiTwzqCnkeQxx9BWx+zPrQsrBFYja
85
+zEfrXL6lfie3khcjY6lSPUGud+G3iA6FrY0uQ/KJsA9gCa0jSvFpnBi6tpKSPu++nsIfDFxeXciR
86
+qIicscY4rxTwB8RUkn1axsPEf2LTYx85kTGzqCUP8VcJ47+JOs+I0Hhq1njjt/ufIeSvq1VtE+Gs
87
+eoaUbSHUrkHdu3WtuX5Ix81XRh7OL5jirVpV5Whdn0F8C/iX4auVn0i612T7bASoe8wjTAd89K9g
88
+vtSt5NMa4t5lkRhgOh3Dn6V8aaz8KZrIR3OlQ6r56LySmSxxz06Vo/CHx34h0rxBP4XvJ5AjK2RP
89
+nEbAEj6ZxjPrWM6fMmoswqJxqJ1VZnqHxn1NLPwveqWHmNC2BnnNcD8DfDkGi+CH1m+ijN1qMzNA
90
+4GSIiAMf+hVxPxU8Tapc3c0F9MGCn5GU5BX0Pau3+HmrT3XgXSIJCBHDGdgAx1NYSpezha52Yauq
91
+1dya2Wh2onAIwTj1p0lxxWWLkhRyCKWa5O3ORXOos9KVQluZm83j0oqi84JyWH50Vdmc7ep43d3I
92
+t1Z2Iz2FYdxeSTsxyRnvTdVuDNcNluM9KrKcg817NOnZGNbEXdkNckjrXGeIIprPxFFdRHAlIwem
93
+COtdmxrG8Q2cd/ZNExw45RvQ1bVjim+dWNzw7eaTD4mN3dndCQCo6hmI5zXpj/Ea/wBHjkh0kwRW
94
+xXEfl4yTxXzXZalJDL9nuWKMmRnHcV2Hh3WreCyYXW2SWQhd5P3F6n+lS43d2cTm6d7Ox9EWPxH1
95
+ODQxPqWpCaSU/ukUc4z3/WvKW8UhviAdaMewYZG98gj9c1ymoa8LyWOJHwkTDaVPb0qpr+q2m6Nb
96
+cfvNo349az9mou9iZVXNWbub3jm98/Vza2ReV7lsJg/e3dsV654UR9N0K0sZP9ZDGFbHr3rzL4P+
97
+H7rXfEEWr3I3W1qf3IYdW9fwqDxf4k8UeH/G95p08kscHmk25dPlZT0we9YTj7SXKjpw1aNG8mj3
98
+FLv5ccU959ycnmvKPDnxB82YQarGsZPAlTp+IrvIr1ZIgySKwIyCOhFYTpyg9T0qWIhVV4svzPvf
99
+IdhgY4orPachj81FRdmtzxqdiZmJ9aQEgdqZcPtmbJ71DJcAZ5r20kkeXJtsfPIQDwPzrG1a+S3i
100
+LyHAHvmp7y7HOD1rlNdm+1T7Acovf3o+J2RMpezjzMvrob67pX9o2ShZlYgg/wAWKxZLLWLZ/Ke3
101
+mVh14yK9M+BMC3dre2ko3LHKCB7EV7EngeGQJdQ7HyBkMKS0djgq1W3c+XtK03U522RwzsTwNiEk
102
+ntXoHgf4calql9El/G8UZbLfLyfr7V9FeGvh+s+0Lbxxcglu2K1NW1nwN4Gk/wBLuI57tV5jjwzE
103
+/QVNS+0dWYRqNvXRFv4eeCodKsY1ggVIY1G3K4z714h+1Jqul3GpwaXYeXJLbzgyyrg4b+6D+HNb
104
+vjz436zq9m+naHF/ZdkeGfOZXH17V4Vqt2b29K+ZuOc5bnce5zWdPBShL2lTfojSeJhy+zp/NjVz
105
+1Bwa6DSfFGq6fbJFDKrov8DjPFcu97ZxsUe4jVhwVJ5Bpp1mwQiLewJPXacVq6fNpYyjOUXdHoKf
106
+EG8VQHsInbuVcgflRXnt5fIs2FYHgcgUVi8LG+xusdW/mN7U2KgEVkTzPt60UVfQ9eHxGHrV1MGi
107
+iD4V25x1qvdgLAMd6KK0pbHm4x++dp8FtUubLxJ5EIjMc+A4Za+qfD8pe1JZVOBmiinW3RyRPMfi
108
+R8QPE638+k2l6LK0Hylbddhb6nOa80mlkcmWR2kcnlnOSaKK7qCXKcNdu5narcSrAoBxvODWJIga
109
+VckjDdqKKwq/EaQ0gUdbjQ6mr7QGBUcd6tPBC6gtGpOOuKKKie5qn7qIpEXd0HSiiimSf//Z`

+ 160
- 0
vendor/src/golang.org/x/crypto/openpgp/packet/userid.go 查看文件

@@ -0,0 +1,160 @@
1
+// Copyright 2011 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
+
5
+package packet
6
+
7
+import (
8
+	"io"
9
+	"io/ioutil"
10
+	"strings"
11
+)
12
+
13
+// UserId contains text that is intended to represent the name and email
14
+// address of the key holder. See RFC 4880, section 5.11. By convention, this
15
+// takes the form "Full Name (Comment) <email@example.com>"
16
+type UserId struct {
17
+	Id string // By convention, this takes the form "Full Name (Comment) <email@example.com>" which is split out in the fields below.
18
+
19
+	Name, Comment, Email string
20
+}
21
+
22
+func hasInvalidCharacters(s string) bool {
23
+	for _, c := range s {
24
+		switch c {
25
+		case '(', ')', '<', '>', 0:
26
+			return true
27
+		}
28
+	}
29
+	return false
30
+}
31
+
32
+// NewUserId returns a UserId or nil if any of the arguments contain invalid
33
+// characters. The invalid characters are '\x00', '(', ')', '<' and '>'
34
+func NewUserId(name, comment, email string) *UserId {
35
+	// RFC 4880 doesn't deal with the structure of userid strings; the
36
+	// name, comment and email form is just a convention. However, there's
37
+	// no convention about escaping the metacharacters and GPG just refuses
38
+	// to create user ids where, say, the name contains a '('. We mirror
39
+	// this behaviour.
40
+
41
+	if hasInvalidCharacters(name) || hasInvalidCharacters(comment) || hasInvalidCharacters(email) {
42
+		return nil
43
+	}
44
+
45
+	uid := new(UserId)
46
+	uid.Name, uid.Comment, uid.Email = name, comment, email
47
+	uid.Id = name
48
+	if len(comment) > 0 {
49
+		if len(uid.Id) > 0 {
50
+			uid.Id += " "
51
+		}
52
+		uid.Id += "("
53
+		uid.Id += comment
54
+		uid.Id += ")"
55
+	}
56
+	if len(email) > 0 {
57
+		if len(uid.Id) > 0 {
58
+			uid.Id += " "
59
+		}
60
+		uid.Id += "<"
61
+		uid.Id += email
62
+		uid.Id += ">"
63
+	}
64
+	return uid
65
+}
66
+
67
+func (uid *UserId) parse(r io.Reader) (err error) {
68
+	// RFC 4880, section 5.11
69
+	b, err := ioutil.ReadAll(r)
70
+	if err != nil {
71
+		return
72
+	}
73
+	uid.Id = string(b)
74
+	uid.Name, uid.Comment, uid.Email = parseUserId(uid.Id)
75
+	return
76
+}
77
+
78
+// Serialize marshals uid to w in the form of an OpenPGP packet, including
79
+// header.
80
+func (uid *UserId) Serialize(w io.Writer) error {
81
+	err := serializeHeader(w, packetTypeUserId, len(uid.Id))
82
+	if err != nil {
83
+		return err
84
+	}
85
+	_, err = w.Write([]byte(uid.Id))
86
+	return err
87
+}
88
+
89
+// parseUserId extracts the name, comment and email from a user id string that
90
+// is formatted as "Full Name (Comment) <email@example.com>".
91
+func parseUserId(id string) (name, comment, email string) {
92
+	var n, c, e struct {
93
+		start, end int
94
+	}
95
+	var state int
96
+
97
+	for offset, rune := range id {
98
+		switch state {
99
+		case 0:
100
+			// Entering name
101
+			n.start = offset
102
+			state = 1
103
+			fallthrough
104
+		case 1:
105
+			// In name
106
+			if rune == '(' {
107
+				state = 2
108
+				n.end = offset
109
+			} else if rune == '<' {
110
+				state = 5
111
+				n.end = offset
112
+			}
113
+		case 2:
114
+			// Entering comment
115
+			c.start = offset
116
+			state = 3
117
+			fallthrough
118
+		case 3:
119
+			// In comment
120
+			if rune == ')' {
121
+				state = 4
122
+				c.end = offset
123
+			}
124
+		case 4:
125
+			// Between comment and email
126
+			if rune == '<' {
127
+				state = 5
128
+			}
129
+		case 5:
130
+			// Entering email
131
+			e.start = offset
132
+			state = 6
133
+			fallthrough
134
+		case 6:
135
+			// In email
136
+			if rune == '>' {
137
+				state = 7
138
+				e.end = offset
139
+			}
140
+		default:
141
+			// After email
142
+		}
143
+	}
144
+	switch state {
145
+	case 1:
146
+		// ended in the name
147
+		n.end = len(id)
148
+	case 3:
149
+		// ended in comment
150
+		c.end = len(id)
151
+	case 6:
152
+		// ended in email
153
+		e.end = len(id)
154
+	}
155
+
156
+	name = strings.TrimSpace(id[n.start:n.end])
157
+	comment = strings.TrimSpace(id[c.start:c.end])
158
+	email = strings.TrimSpace(id[e.start:e.end])
159
+	return
160
+}

+ 87
- 0
vendor/src/golang.org/x/crypto/openpgp/packet/userid_test.go 查看文件

@@ -0,0 +1,87 @@
1
+// Copyright 2011 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
+
5
+package packet
6
+
7
+import (
8
+	"testing"
9
+)
10
+
11
+var userIdTests = []struct {
12
+	id                   string
13
+	name, comment, email string
14
+}{
15
+	{"", "", "", ""},
16
+	{"John Smith", "John Smith", "", ""},
17
+	{"John Smith ()", "John Smith", "", ""},
18
+	{"John Smith () <>", "John Smith", "", ""},
19
+	{"(comment", "", "comment", ""},
20
+	{"(comment)", "", "comment", ""},
21
+	{"<email", "", "", "email"},
22
+	{"<email>   sdfk", "", "", "email"},
23
+	{"  John Smith  (  Comment ) asdkflj < email > lksdfj", "John Smith", "Comment", "email"},
24
+	{"  John Smith  < email > lksdfj", "John Smith", "", "email"},
25
+	{"(<foo", "", "<foo", ""},
26
+	{"René Descartes (العربي)", "René Descartes", "العربي", ""},
27
+}
28
+
29
+func TestParseUserId(t *testing.T) {
30
+	for i, test := range userIdTests {
31
+		name, comment, email := parseUserId(test.id)
32
+		if name != test.name {
33
+			t.Errorf("%d: name mismatch got:%s want:%s", i, name, test.name)
34
+		}
35
+		if comment != test.comment {
36
+			t.Errorf("%d: comment mismatch got:%s want:%s", i, comment, test.comment)
37
+		}
38
+		if email != test.email {
39
+			t.Errorf("%d: email mismatch got:%s want:%s", i, email, test.email)
40
+		}
41
+	}
42
+}
43
+
44
+var newUserIdTests = []struct {
45
+	name, comment, email, id string
46
+}{
47
+	{"foo", "", "", "foo"},
48
+	{"", "bar", "", "(bar)"},
49
+	{"", "", "baz", "<baz>"},
50
+	{"foo", "bar", "", "foo (bar)"},
51
+	{"foo", "", "baz", "foo <baz>"},
52
+	{"", "bar", "baz", "(bar) <baz>"},
53
+	{"foo", "bar", "baz", "foo (bar) <baz>"},
54
+}
55
+
56
+func TestNewUserId(t *testing.T) {
57
+	for i, test := range newUserIdTests {
58
+		uid := NewUserId(test.name, test.comment, test.email)
59
+		if uid == nil {
60
+			t.Errorf("#%d: returned nil", i)
61
+			continue
62
+		}
63
+		if uid.Id != test.id {
64
+			t.Errorf("#%d: got '%s', want '%s'", i, uid.Id, test.id)
65
+		}
66
+	}
67
+}
68
+
69
+var invalidNewUserIdTests = []struct {
70
+	name, comment, email string
71
+}{
72
+	{"foo(", "", ""},
73
+	{"foo<", "", ""},
74
+	{"", "bar)", ""},
75
+	{"", "bar<", ""},
76
+	{"", "", "baz>"},
77
+	{"", "", "baz)"},
78
+	{"", "", "baz\x00"},
79
+}
80
+
81
+func TestNewUserIdWithInvalidInput(t *testing.T) {
82
+	for i, test := range invalidNewUserIdTests {
83
+		if uid := NewUserId(test.name, test.comment, test.email); uid != nil {
84
+			t.Errorf("#%d: returned non-nil value: %#v", i, uid)
85
+		}
86
+	}
87
+}

+ 442
- 0
vendor/src/golang.org/x/crypto/openpgp/read.go 查看文件

@@ -0,0 +1,442 @@
1
+// Copyright 2011 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
+
5
+// Package openpgp implements high level operations on OpenPGP messages.
6
+package openpgp // import "golang.org/x/crypto/openpgp"
7
+
8
+import (
9
+	"crypto"
10
+	_ "crypto/sha256"
11
+	"hash"
12
+	"io"
13
+	"strconv"
14
+
15
+	"golang.org/x/crypto/openpgp/armor"
16
+	"golang.org/x/crypto/openpgp/errors"
17
+	"golang.org/x/crypto/openpgp/packet"
18
+)
19
+
20
+// SignatureType is the armor type for a PGP signature.
21
+var SignatureType = "PGP SIGNATURE"
22
+
23
+// readArmored reads an armored block with the given type.
24
+func readArmored(r io.Reader, expectedType string) (body io.Reader, err error) {
25
+	block, err := armor.Decode(r)
26
+	if err != nil {
27
+		return
28
+	}
29
+
30
+	if block.Type != expectedType {
31
+		return nil, errors.InvalidArgumentError("expected '" + expectedType + "', got: " + block.Type)
32
+	}
33
+
34
+	return block.Body, nil
35
+}
36
+
37
+// MessageDetails contains the result of parsing an OpenPGP encrypted and/or
38
+// signed message.
39
+type MessageDetails struct {
40
+	IsEncrypted              bool                // true if the message was encrypted.
41
+	EncryptedToKeyIds        []uint64            // the list of recipient key ids.
42
+	IsSymmetricallyEncrypted bool                // true if a passphrase could have decrypted the message.
43
+	DecryptedWith            Key                 // the private key used to decrypt the message, if any.
44
+	IsSigned                 bool                // true if the message is signed.
45
+	SignedByKeyId            uint64              // the key id of the signer, if any.
46
+	SignedBy                 *Key                // the key of the signer, if available.
47
+	LiteralData              *packet.LiteralData // the metadata of the contents
48
+	UnverifiedBody           io.Reader           // the contents of the message.
49
+
50
+	// If IsSigned is true and SignedBy is non-zero then the signature will
51
+	// be verified as UnverifiedBody is read. The signature cannot be
52
+	// checked until the whole of UnverifiedBody is read so UnverifiedBody
53
+	// must be consumed until EOF before the data can be trusted. Even if a
54
+	// message isn't signed (or the signer is unknown) the data may contain
55
+	// an authentication code that is only checked once UnverifiedBody has
56
+	// been consumed. Once EOF has been seen, the following fields are
57
+	// valid. (An authentication code failure is reported as a
58
+	// SignatureError error when reading from UnverifiedBody.)
59
+	SignatureError error               // nil if the signature is good.
60
+	Signature      *packet.Signature   // the signature packet itself, if v4 (default)
61
+	SignatureV3    *packet.SignatureV3 // the signature packet if it is a v2 or v3 signature
62
+
63
+	decrypted io.ReadCloser
64
+}
65
+
66
+// A PromptFunction is used as a callback by functions that may need to decrypt
67
+// a private key, or prompt for a passphrase. It is called with a list of
68
+// acceptable, encrypted private keys and a boolean that indicates whether a
69
+// passphrase is usable. It should either decrypt a private key or return a
70
+// passphrase to try. If the decrypted private key or given passphrase isn't
71
+// correct, the function will be called again, forever. Any error returned will
72
+// be passed up.
73
+type PromptFunction func(keys []Key, symmetric bool) ([]byte, error)
74
+
75
+// A keyEnvelopePair is used to store a private key with the envelope that
76
+// contains a symmetric key, encrypted with that key.
77
+type keyEnvelopePair struct {
78
+	key          Key
79
+	encryptedKey *packet.EncryptedKey
80
+}
81
+
82
+// ReadMessage parses an OpenPGP message that may be signed and/or encrypted.
83
+// The given KeyRing should contain both public keys (for signature
84
+// verification) and, possibly encrypted, private keys for decrypting.
85
+// If config is nil, sensible defaults will be used.
86
+func ReadMessage(r io.Reader, keyring KeyRing, prompt PromptFunction, config *packet.Config) (md *MessageDetails, err error) {
87
+	var p packet.Packet
88
+
89
+	var symKeys []*packet.SymmetricKeyEncrypted
90
+	var pubKeys []keyEnvelopePair
91
+	var se *packet.SymmetricallyEncrypted
92
+
93
+	packets := packet.NewReader(r)
94
+	md = new(MessageDetails)
95
+	md.IsEncrypted = true
96
+
97
+	// The message, if encrypted, starts with a number of packets
98
+	// containing an encrypted decryption key. The decryption key is either
99
+	// encrypted to a public key, or with a passphrase. This loop
100
+	// collects these packets.
101
+ParsePackets:
102
+	for {
103
+		p, err = packets.Next()
104
+		if err != nil {
105
+			return nil, err
106
+		}
107
+		switch p := p.(type) {
108
+		case *packet.SymmetricKeyEncrypted:
109
+			// This packet contains the decryption key encrypted with a passphrase.
110
+			md.IsSymmetricallyEncrypted = true
111
+			symKeys = append(symKeys, p)
112
+		case *packet.EncryptedKey:
113
+			// This packet contains the decryption key encrypted to a public key.
114
+			md.EncryptedToKeyIds = append(md.EncryptedToKeyIds, p.KeyId)
115
+			switch p.Algo {
116
+			case packet.PubKeyAlgoRSA, packet.PubKeyAlgoRSAEncryptOnly, packet.PubKeyAlgoElGamal:
117
+				break
118
+			default:
119
+				continue
120
+			}
121
+			var keys []Key
122
+			if p.KeyId == 0 {
123
+				keys = keyring.DecryptionKeys()
124
+			} else {
125
+				keys = keyring.KeysById(p.KeyId)
126
+			}
127
+			for _, k := range keys {
128
+				pubKeys = append(pubKeys, keyEnvelopePair{k, p})
129
+			}
130
+		case *packet.SymmetricallyEncrypted:
131
+			se = p
132
+			break ParsePackets
133
+		case *packet.Compressed, *packet.LiteralData, *packet.OnePassSignature:
134
+			// This message isn't encrypted.
135
+			if len(symKeys) != 0 || len(pubKeys) != 0 {
136
+				return nil, errors.StructuralError("key material not followed by encrypted message")
137
+			}
138
+			packets.Unread(p)
139
+			return readSignedMessage(packets, nil, keyring)
140
+		}
141
+	}
142
+
143
+	var candidates []Key
144
+	var decrypted io.ReadCloser
145
+
146
+	// Now that we have the list of encrypted keys we need to decrypt at
147
+	// least one of them or, if we cannot, we need to call the prompt
148
+	// function so that it can decrypt a key or give us a passphrase.
149
+FindKey:
150
+	for {
151
+		// See if any of the keys already have a private key available
152
+		candidates = candidates[:0]
153
+		candidateFingerprints := make(map[string]bool)
154
+
155
+		for _, pk := range pubKeys {
156
+			if pk.key.PrivateKey == nil {
157
+				continue
158
+			}
159
+			if !pk.key.PrivateKey.Encrypted {
160
+				if len(pk.encryptedKey.Key) == 0 {
161
+					pk.encryptedKey.Decrypt(pk.key.PrivateKey, config)
162
+				}
163
+				if len(pk.encryptedKey.Key) == 0 {
164
+					continue
165
+				}
166
+				decrypted, err = se.Decrypt(pk.encryptedKey.CipherFunc, pk.encryptedKey.Key)
167
+				if err != nil && err != errors.ErrKeyIncorrect {
168
+					return nil, err
169
+				}
170
+				if decrypted != nil {
171
+					md.DecryptedWith = pk.key
172
+					break FindKey
173
+				}
174
+			} else {
175
+				fpr := string(pk.key.PublicKey.Fingerprint[:])
176
+				if v := candidateFingerprints[fpr]; v {
177
+					continue
178
+				}
179
+				candidates = append(candidates, pk.key)
180
+				candidateFingerprints[fpr] = true
181
+			}
182
+		}
183
+
184
+		if len(candidates) == 0 && len(symKeys) == 0 {
185
+			return nil, errors.ErrKeyIncorrect
186
+		}
187
+
188
+		if prompt == nil {
189
+			return nil, errors.ErrKeyIncorrect
190
+		}
191
+
192
+		passphrase, err := prompt(candidates, len(symKeys) != 0)
193
+		if err != nil {
194
+			return nil, err
195
+		}
196
+
197
+		// Try the symmetric passphrase first
198
+		if len(symKeys) != 0 && passphrase != nil {
199
+			for _, s := range symKeys {
200
+				key, cipherFunc, err := s.Decrypt(passphrase)
201
+				if err == nil {
202
+					decrypted, err = se.Decrypt(cipherFunc, key)
203
+					if err != nil && err != errors.ErrKeyIncorrect {
204
+						return nil, err
205
+					}
206
+					if decrypted != nil {
207
+						break FindKey
208
+					}
209
+				}
210
+
211
+			}
212
+		}
213
+	}
214
+
215
+	md.decrypted = decrypted
216
+	if err := packets.Push(decrypted); err != nil {
217
+		return nil, err
218
+	}
219
+	return readSignedMessage(packets, md, keyring)
220
+}
221
+
222
+// readSignedMessage reads a possibly signed message if mdin is non-zero then
223
+// that structure is updated and returned. Otherwise a fresh MessageDetails is
224
+// used.
225
+func readSignedMessage(packets *packet.Reader, mdin *MessageDetails, keyring KeyRing) (md *MessageDetails, err error) {
226
+	if mdin == nil {
227
+		mdin = new(MessageDetails)
228
+	}
229
+	md = mdin
230
+
231
+	var p packet.Packet
232
+	var h hash.Hash
233
+	var wrappedHash hash.Hash
234
+FindLiteralData:
235
+	for {
236
+		p, err = packets.Next()
237
+		if err != nil {
238
+			return nil, err
239
+		}
240
+		switch p := p.(type) {
241
+		case *packet.Compressed:
242
+			if err := packets.Push(p.Body); err != nil {
243
+				return nil, err
244
+			}
245
+		case *packet.OnePassSignature:
246
+			if !p.IsLast {
247
+				return nil, errors.UnsupportedError("nested signatures")
248
+			}
249
+
250
+			h, wrappedHash, err = hashForSignature(p.Hash, p.SigType)
251
+			if err != nil {
252
+				md = nil
253
+				return
254
+			}
255
+
256
+			md.IsSigned = true
257
+			md.SignedByKeyId = p.KeyId
258
+			keys := keyring.KeysByIdUsage(p.KeyId, packet.KeyFlagSign)
259
+			if len(keys) > 0 {
260
+				md.SignedBy = &keys[0]
261
+			}
262
+		case *packet.LiteralData:
263
+			md.LiteralData = p
264
+			break FindLiteralData
265
+		}
266
+	}
267
+
268
+	if md.SignedBy != nil {
269
+		md.UnverifiedBody = &signatureCheckReader{packets, h, wrappedHash, md}
270
+	} else if md.decrypted != nil {
271
+		md.UnverifiedBody = checkReader{md}
272
+	} else {
273
+		md.UnverifiedBody = md.LiteralData.Body
274
+	}
275
+
276
+	return md, nil
277
+}
278
+
279
+// hashForSignature returns a pair of hashes that can be used to verify a
280
+// signature. The signature may specify that the contents of the signed message
281
+// should be preprocessed (i.e. to normalize line endings). Thus this function
282
+// returns two hashes. The second should be used to hash the message itself and
283
+// performs any needed preprocessing.
284
+func hashForSignature(hashId crypto.Hash, sigType packet.SignatureType) (hash.Hash, hash.Hash, error) {
285
+	if !hashId.Available() {
286
+		return nil, nil, errors.UnsupportedError("hash not available: " + strconv.Itoa(int(hashId)))
287
+	}
288
+	h := hashId.New()
289
+
290
+	switch sigType {
291
+	case packet.SigTypeBinary:
292
+		return h, h, nil
293
+	case packet.SigTypeText:
294
+		return h, NewCanonicalTextHash(h), nil
295
+	}
296
+
297
+	return nil, nil, errors.UnsupportedError("unsupported signature type: " + strconv.Itoa(int(sigType)))
298
+}
299
+
300
+// checkReader wraps an io.Reader from a LiteralData packet. When it sees EOF
301
+// it closes the ReadCloser from any SymmetricallyEncrypted packet to trigger
302
+// MDC checks.
303
+type checkReader struct {
304
+	md *MessageDetails
305
+}
306
+
307
+func (cr checkReader) Read(buf []byte) (n int, err error) {
308
+	n, err = cr.md.LiteralData.Body.Read(buf)
309
+	if err == io.EOF {
310
+		mdcErr := cr.md.decrypted.Close()
311
+		if mdcErr != nil {
312
+			err = mdcErr
313
+		}
314
+	}
315
+	return
316
+}
317
+
318
+// signatureCheckReader wraps an io.Reader from a LiteralData packet and hashes
319
+// the data as it is read. When it sees an EOF from the underlying io.Reader
320
+// it parses and checks a trailing Signature packet and triggers any MDC checks.
321
+type signatureCheckReader struct {
322
+	packets        *packet.Reader
323
+	h, wrappedHash hash.Hash
324
+	md             *MessageDetails
325
+}
326
+
327
+func (scr *signatureCheckReader) Read(buf []byte) (n int, err error) {
328
+	n, err = scr.md.LiteralData.Body.Read(buf)
329
+	scr.wrappedHash.Write(buf[:n])
330
+	if err == io.EOF {
331
+		var p packet.Packet
332
+		p, scr.md.SignatureError = scr.packets.Next()
333
+		if scr.md.SignatureError != nil {
334
+			return
335
+		}
336
+
337
+		var ok bool
338
+		if scr.md.Signature, ok = p.(*packet.Signature); ok {
339
+			scr.md.SignatureError = scr.md.SignedBy.PublicKey.VerifySignature(scr.h, scr.md.Signature)
340
+		} else if scr.md.SignatureV3, ok = p.(*packet.SignatureV3); ok {
341
+			scr.md.SignatureError = scr.md.SignedBy.PublicKey.VerifySignatureV3(scr.h, scr.md.SignatureV3)
342
+		} else {
343
+			scr.md.SignatureError = errors.StructuralError("LiteralData not followed by Signature")
344
+			return
345
+		}
346
+
347
+		// The SymmetricallyEncrypted packet, if any, might have an
348
+		// unsigned hash of its own. In order to check this we need to
349
+		// close that Reader.
350
+		if scr.md.decrypted != nil {
351
+			mdcErr := scr.md.decrypted.Close()
352
+			if mdcErr != nil {
353
+				err = mdcErr
354
+			}
355
+		}
356
+	}
357
+	return
358
+}
359
+
360
+// CheckDetachedSignature takes a signed file and a detached signature and
361
+// returns the signer if the signature is valid. If the signer isn't known,
362
+// ErrUnknownIssuer is returned.
363
+func CheckDetachedSignature(keyring KeyRing, signed, signature io.Reader) (signer *Entity, err error) {
364
+	var issuerKeyId uint64
365
+	var hashFunc crypto.Hash
366
+	var sigType packet.SignatureType
367
+	var keys []Key
368
+	var p packet.Packet
369
+
370
+	packets := packet.NewReader(signature)
371
+	for {
372
+		p, err = packets.Next()
373
+		if err == io.EOF {
374
+			return nil, errors.ErrUnknownIssuer
375
+		}
376
+		if err != nil {
377
+			return nil, err
378
+		}
379
+
380
+		switch sig := p.(type) {
381
+		case *packet.Signature:
382
+			if sig.IssuerKeyId == nil {
383
+				return nil, errors.StructuralError("signature doesn't have an issuer")
384
+			}
385
+			issuerKeyId = *sig.IssuerKeyId
386
+			hashFunc = sig.Hash
387
+			sigType = sig.SigType
388
+		case *packet.SignatureV3:
389
+			issuerKeyId = sig.IssuerKeyId
390
+			hashFunc = sig.Hash
391
+			sigType = sig.SigType
392
+		default:
393
+			return nil, errors.StructuralError("non signature packet found")
394
+		}
395
+
396
+		keys = keyring.KeysByIdUsage(issuerKeyId, packet.KeyFlagSign)
397
+		if len(keys) > 0 {
398
+			break
399
+		}
400
+	}
401
+
402
+	if len(keys) == 0 {
403
+		panic("unreachable")
404
+	}
405
+
406
+	h, wrappedHash, err := hashForSignature(hashFunc, sigType)
407
+	if err != nil {
408
+		return nil, err
409
+	}
410
+
411
+	if _, err := io.Copy(wrappedHash, signed); err != nil && err != io.EOF {
412
+		return nil, err
413
+	}
414
+
415
+	for _, key := range keys {
416
+		switch sig := p.(type) {
417
+		case *packet.Signature:
418
+			err = key.PublicKey.VerifySignature(h, sig)
419
+		case *packet.SignatureV3:
420
+			err = key.PublicKey.VerifySignatureV3(h, sig)
421
+		default:
422
+			panic("unreachable")
423
+		}
424
+
425
+		if err == nil {
426
+			return key.Entity, nil
427
+		}
428
+	}
429
+
430
+	return nil, err
431
+}
432
+
433
+// CheckArmoredDetachedSignature performs the same actions as
434
+// CheckDetachedSignature but expects the signature to be armored.
435
+func CheckArmoredDetachedSignature(keyring KeyRing, signed, signature io.Reader) (signer *Entity, err error) {
436
+	body, err := readArmored(signature, SignatureType)
437
+	if err != nil {
438
+		return
439
+	}
440
+
441
+	return CheckDetachedSignature(keyring, signed, body)
442
+}

+ 613
- 0
vendor/src/golang.org/x/crypto/openpgp/read_test.go
文件差异内容过多而无法显示
查看文件


+ 273
- 0
vendor/src/golang.org/x/crypto/openpgp/s2k/s2k.go 查看文件

@@ -0,0 +1,273 @@
1
+// Copyright 2011 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
+
5
+// Package s2k implements the various OpenPGP string-to-key transforms as
6
+// specified in RFC 4800 section 3.7.1.
7
+package s2k // import "golang.org/x/crypto/openpgp/s2k"
8
+
9
+import (
10
+	"crypto"
11
+	"hash"
12
+	"io"
13
+	"strconv"
14
+
15
+	"golang.org/x/crypto/openpgp/errors"
16
+)
17
+
18
+// Config collects configuration parameters for s2k key-stretching
19
+// transformatioms. A nil *Config is valid and results in all default
20
+// values. Currently, Config is used only by the Serialize function in
21
+// this package.
22
+type Config struct {
23
+	// Hash is the default hash function to be used. If
24
+	// nil, SHA1 is used.
25
+	Hash crypto.Hash
26
+	// S2KCount is only used for symmetric encryption. It
27
+	// determines the strength of the passphrase stretching when
28
+	// the said passphrase is hashed to produce a key. S2KCount
29
+	// should be between 1024 and 65011712, inclusive. If Config
30
+	// is nil or S2KCount is 0, the value 65536 used. Not all
31
+	// values in the above range can be represented. S2KCount will
32
+	// be rounded up to the next representable value if it cannot
33
+	// be encoded exactly. When set, it is strongly encrouraged to
34
+	// use a value that is at least 65536. See RFC 4880 Section
35
+	// 3.7.1.3.
36
+	S2KCount int
37
+}
38
+
39
+func (c *Config) hash() crypto.Hash {
40
+	if c == nil || uint(c.Hash) == 0 {
41
+		// SHA1 is the historical default in this package.
42
+		return crypto.SHA1
43
+	}
44
+
45
+	return c.Hash
46
+}
47
+
48
+func (c *Config) encodedCount() uint8 {
49
+	if c == nil || c.S2KCount == 0 {
50
+		return 96 // The common case. Correspoding to 65536
51
+	}
52
+
53
+	i := c.S2KCount
54
+	switch {
55
+	// Behave like GPG. Should we make 65536 the lowest value used?
56
+	case i < 1024:
57
+		i = 1024
58
+	case i > 65011712:
59
+		i = 65011712
60
+	}
61
+
62
+	return encodeCount(i)
63
+}
64
+
65
+// encodeCount converts an iterative "count" in the range 1024 to
66
+// 65011712, inclusive, to an encoded count. The return value is the
67
+// octet that is actually stored in the GPG file. encodeCount panics
68
+// if i is not in the above range (encodedCount above takes care to
69
+// pass i in the correct range). See RFC 4880 Section 3.7.7.1.
70
+func encodeCount(i int) uint8 {
71
+	if i < 1024 || i > 65011712 {
72
+		panic("count arg i outside the required range")
73
+	}
74
+
75
+	for encoded := 0; encoded < 256; encoded++ {
76
+		count := decodeCount(uint8(encoded))
77
+		if count >= i {
78
+			return uint8(encoded)
79
+		}
80
+	}
81
+
82
+	return 255
83
+}
84
+
85
+// decodeCount returns the s2k mode 3 iterative "count" corresponding to
86
+// the encoded octet c.
87
+func decodeCount(c uint8) int {
88
+	return (16 + int(c&15)) << (uint32(c>>4) + 6)
89
+}
90
+
91
+// Simple writes to out the result of computing the Simple S2K function (RFC
92
+// 4880, section 3.7.1.1) using the given hash and input passphrase.
93
+func Simple(out []byte, h hash.Hash, in []byte) {
94
+	Salted(out, h, in, nil)
95
+}
96
+
97
+var zero [1]byte
98
+
99
+// Salted writes to out the result of computing the Salted S2K function (RFC
100
+// 4880, section 3.7.1.2) using the given hash, input passphrase and salt.
101
+func Salted(out []byte, h hash.Hash, in []byte, salt []byte) {
102
+	done := 0
103
+	var digest []byte
104
+
105
+	for i := 0; done < len(out); i++ {
106
+		h.Reset()
107
+		for j := 0; j < i; j++ {
108
+			h.Write(zero[:])
109
+		}
110
+		h.Write(salt)
111
+		h.Write(in)
112
+		digest = h.Sum(digest[:0])
113
+		n := copy(out[done:], digest)
114
+		done += n
115
+	}
116
+}
117
+
118
+// Iterated writes to out the result of computing the Iterated and Salted S2K
119
+// function (RFC 4880, section 3.7.1.3) using the given hash, input passphrase,
120
+// salt and iteration count.
121
+func Iterated(out []byte, h hash.Hash, in []byte, salt []byte, count int) {
122
+	combined := make([]byte, len(in)+len(salt))
123
+	copy(combined, salt)
124
+	copy(combined[len(salt):], in)
125
+
126
+	if count < len(combined) {
127
+		count = len(combined)
128
+	}
129
+
130
+	done := 0
131
+	var digest []byte
132
+	for i := 0; done < len(out); i++ {
133
+		h.Reset()
134
+		for j := 0; j < i; j++ {
135
+			h.Write(zero[:])
136
+		}
137
+		written := 0
138
+		for written < count {
139
+			if written+len(combined) > count {
140
+				todo := count - written
141
+				h.Write(combined[:todo])
142
+				written = count
143
+			} else {
144
+				h.Write(combined)
145
+				written += len(combined)
146
+			}
147
+		}
148
+		digest = h.Sum(digest[:0])
149
+		n := copy(out[done:], digest)
150
+		done += n
151
+	}
152
+}
153
+
154
+// Parse reads a binary specification for a string-to-key transformation from r
155
+// and returns a function which performs that transform.
156
+func Parse(r io.Reader) (f func(out, in []byte), err error) {
157
+	var buf [9]byte
158
+
159
+	_, err = io.ReadFull(r, buf[:2])
160
+	if err != nil {
161
+		return
162
+	}
163
+
164
+	hash, ok := HashIdToHash(buf[1])
165
+	if !ok {
166
+		return nil, errors.UnsupportedError("hash for S2K function: " + strconv.Itoa(int(buf[1])))
167
+	}
168
+	if !hash.Available() {
169
+		return nil, errors.UnsupportedError("hash not available: " + strconv.Itoa(int(hash)))
170
+	}
171
+	h := hash.New()
172
+
173
+	switch buf[0] {
174
+	case 0:
175
+		f := func(out, in []byte) {
176
+			Simple(out, h, in)
177
+		}
178
+		return f, nil
179
+	case 1:
180
+		_, err = io.ReadFull(r, buf[:8])
181
+		if err != nil {
182
+			return
183
+		}
184
+		f := func(out, in []byte) {
185
+			Salted(out, h, in, buf[:8])
186
+		}
187
+		return f, nil
188
+	case 3:
189
+		_, err = io.ReadFull(r, buf[:9])
190
+		if err != nil {
191
+			return
192
+		}
193
+		count := decodeCount(buf[8])
194
+		f := func(out, in []byte) {
195
+			Iterated(out, h, in, buf[:8], count)
196
+		}
197
+		return f, nil
198
+	}
199
+
200
+	return nil, errors.UnsupportedError("S2K function")
201
+}
202
+
203
+// Serialize salts and stretches the given passphrase and writes the
204
+// resulting key into key. It also serializes an S2K descriptor to
205
+// w. The key stretching can be configured with c, which may be
206
+// nil. In that case, sensible defaults will be used.
207
+func Serialize(w io.Writer, key []byte, rand io.Reader, passphrase []byte, c *Config) error {
208
+	var buf [11]byte
209
+	buf[0] = 3 /* iterated and salted */
210
+	buf[1], _ = HashToHashId(c.hash())
211
+	salt := buf[2:10]
212
+	if _, err := io.ReadFull(rand, salt); err != nil {
213
+		return err
214
+	}
215
+	encodedCount := c.encodedCount()
216
+	count := decodeCount(encodedCount)
217
+	buf[10] = encodedCount
218
+	if _, err := w.Write(buf[:]); err != nil {
219
+		return err
220
+	}
221
+
222
+	Iterated(key, c.hash().New(), passphrase, salt, count)
223
+	return nil
224
+}
225
+
226
+// hashToHashIdMapping contains pairs relating OpenPGP's hash identifier with
227
+// Go's crypto.Hash type. See RFC 4880, section 9.4.
228
+var hashToHashIdMapping = []struct {
229
+	id   byte
230
+	hash crypto.Hash
231
+	name string
232
+}{
233
+	{1, crypto.MD5, "MD5"},
234
+	{2, crypto.SHA1, "SHA1"},
235
+	{3, crypto.RIPEMD160, "RIPEMD160"},
236
+	{8, crypto.SHA256, "SHA256"},
237
+	{9, crypto.SHA384, "SHA384"},
238
+	{10, crypto.SHA512, "SHA512"},
239
+	{11, crypto.SHA224, "SHA224"},
240
+}
241
+
242
+// HashIdToHash returns a crypto.Hash which corresponds to the given OpenPGP
243
+// hash id.
244
+func HashIdToHash(id byte) (h crypto.Hash, ok bool) {
245
+	for _, m := range hashToHashIdMapping {
246
+		if m.id == id {
247
+			return m.hash, true
248
+		}
249
+	}
250
+	return 0, false
251
+}
252
+
253
+// HashIdToString returns the name of the hash function corresponding to the
254
+// given OpenPGP hash id.
255
+func HashIdToString(id byte) (name string, ok bool) {
256
+	for _, m := range hashToHashIdMapping {
257
+		if m.id == id {
258
+			return m.name, true
259
+		}
260
+	}
261
+
262
+	return "", false
263
+}
264
+
265
+// HashIdToHash returns an OpenPGP hash id which corresponds the given Hash.
266
+func HashToHashId(h crypto.Hash) (id byte, ok bool) {
267
+	for _, m := range hashToHashIdMapping {
268
+		if m.hash == h {
269
+			return m.id, true
270
+		}
271
+	}
272
+	return 0, false
273
+}

+ 137
- 0
vendor/src/golang.org/x/crypto/openpgp/s2k/s2k_test.go 查看文件

@@ -0,0 +1,137 @@
1
+// Copyright 2011 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
+
5
+package s2k
6
+
7
+import (
8
+	"bytes"
9
+	"crypto"
10
+	_ "crypto/md5"
11
+	"crypto/rand"
12
+	"crypto/sha1"
13
+	_ "crypto/sha256"
14
+	_ "crypto/sha512"
15
+	"encoding/hex"
16
+	"testing"
17
+
18
+	_ "golang.org/x/crypto/ripemd160"
19
+)
20
+
21
+var saltedTests = []struct {
22
+	in, out string
23
+}{
24
+	{"hello", "10295ac1"},
25
+	{"world", "ac587a5e"},
26
+	{"foo", "4dda8077"},
27
+	{"bar", "bd8aac6b9ea9cae04eae6a91c6133b58b5d9a61c14f355516ed9370456"},
28
+	{"x", "f1d3f289"},
29
+	{"xxxxxxxxxxxxxxxxxxxxxxx", "e00d7b45"},
30
+}
31
+
32
+func TestSalted(t *testing.T) {
33
+	h := sha1.New()
34
+	salt := [4]byte{1, 2, 3, 4}
35
+
36
+	for i, test := range saltedTests {
37
+		expected, _ := hex.DecodeString(test.out)
38
+		out := make([]byte, len(expected))
39
+		Salted(out, h, []byte(test.in), salt[:])
40
+		if !bytes.Equal(expected, out) {
41
+			t.Errorf("#%d, got: %x want: %x", i, out, expected)
42
+		}
43
+	}
44
+}
45
+
46
+var iteratedTests = []struct {
47
+	in, out string
48
+}{
49
+	{"hello", "83126105"},
50
+	{"world", "6fa317f9"},
51
+	{"foo", "8fbc35b9"},
52
+	{"bar", "2af5a99b54f093789fd657f19bd245af7604d0f6ae06f66602a46a08ae"},
53
+	{"x", "5a684dfe"},
54
+	{"xxxxxxxxxxxxxxxxxxxxxxx", "18955174"},
55
+}
56
+
57
+func TestIterated(t *testing.T) {
58
+	h := sha1.New()
59
+	salt := [4]byte{4, 3, 2, 1}
60
+
61
+	for i, test := range iteratedTests {
62
+		expected, _ := hex.DecodeString(test.out)
63
+		out := make([]byte, len(expected))
64
+		Iterated(out, h, []byte(test.in), salt[:], 31)
65
+		if !bytes.Equal(expected, out) {
66
+			t.Errorf("#%d, got: %x want: %x", i, out, expected)
67
+		}
68
+	}
69
+}
70
+
71
+var parseTests = []struct {
72
+	spec, in, out string
73
+}{
74
+	/* Simple with SHA1 */
75
+	{"0002", "hello", "aaf4c61d"},
76
+	/* Salted with SHA1 */
77
+	{"01020102030405060708", "hello", "f4f7d67e"},
78
+	/* Iterated with SHA1 */
79
+	{"03020102030405060708f1", "hello", "f2a57b7c"},
80
+}
81
+
82
+func TestParse(t *testing.T) {
83
+	for i, test := range parseTests {
84
+		spec, _ := hex.DecodeString(test.spec)
85
+		buf := bytes.NewBuffer(spec)
86
+		f, err := Parse(buf)
87
+		if err != nil {
88
+			t.Errorf("%d: Parse returned error: %s", i, err)
89
+			continue
90
+		}
91
+
92
+		expected, _ := hex.DecodeString(test.out)
93
+		out := make([]byte, len(expected))
94
+		f(out, []byte(test.in))
95
+		if !bytes.Equal(out, expected) {
96
+			t.Errorf("%d: output got: %x want: %x", i, out, expected)
97
+		}
98
+		if testing.Short() {
99
+			break
100
+		}
101
+	}
102
+}
103
+
104
+func TestSerialize(t *testing.T) {
105
+	hashes := []crypto.Hash{crypto.MD5, crypto.SHA1, crypto.RIPEMD160,
106
+		crypto.SHA256, crypto.SHA384, crypto.SHA512, crypto.SHA224}
107
+	testCounts := []int{-1, 0, 1024, 65536, 4063232, 65011712}
108
+	for _, h := range hashes {
109
+		for _, c := range testCounts {
110
+			testSerializeConfig(t, &Config{Hash: h, S2KCount: c})
111
+		}
112
+	}
113
+}
114
+
115
+func testSerializeConfig(t *testing.T, c *Config) {
116
+	t.Logf("Running testSerializeConfig() with config: %+v", c)
117
+
118
+	buf := bytes.NewBuffer(nil)
119
+	key := make([]byte, 16)
120
+	passphrase := []byte("testing")
121
+	err := Serialize(buf, key, rand.Reader, passphrase, c)
122
+	if err != nil {
123
+		t.Errorf("failed to serialize: %s", err)
124
+		return
125
+	}
126
+
127
+	f, err := Parse(buf)
128
+	if err != nil {
129
+		t.Errorf("failed to reparse: %s", err)
130
+		return
131
+	}
132
+	key2 := make([]byte, len(key))
133
+	f(key2, passphrase)
134
+	if !bytes.Equal(key2, key) {
135
+		t.Errorf("keys don't match: %x (serialied) vs %x (parsed)", key, key2)
136
+	}
137
+}

+ 378
- 0
vendor/src/golang.org/x/crypto/openpgp/write.go 查看文件

@@ -0,0 +1,378 @@
1
+// Copyright 2011 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
+
5
+package openpgp
6
+
7
+import (
8
+	"crypto"
9
+	"hash"
10
+	"io"
11
+	"strconv"
12
+	"time"
13
+
14
+	"golang.org/x/crypto/openpgp/armor"
15
+	"golang.org/x/crypto/openpgp/errors"
16
+	"golang.org/x/crypto/openpgp/packet"
17
+	"golang.org/x/crypto/openpgp/s2k"
18
+)
19
+
20
+// DetachSign signs message with the private key from signer (which must
21
+// already have been decrypted) and writes the signature to w.
22
+// If config is nil, sensible defaults will be used.
23
+func DetachSign(w io.Writer, signer *Entity, message io.Reader, config *packet.Config) error {
24
+	return detachSign(w, signer, message, packet.SigTypeBinary, config)
25
+}
26
+
27
+// ArmoredDetachSign signs message with the private key from signer (which
28
+// must already have been decrypted) and writes an armored signature to w.
29
+// If config is nil, sensible defaults will be used.
30
+func ArmoredDetachSign(w io.Writer, signer *Entity, message io.Reader, config *packet.Config) (err error) {
31
+	return armoredDetachSign(w, signer, message, packet.SigTypeBinary, config)
32
+}
33
+
34
+// DetachSignText signs message (after canonicalising the line endings) with
35
+// the private key from signer (which must already have been decrypted) and
36
+// writes the signature to w.
37
+// If config is nil, sensible defaults will be used.
38
+func DetachSignText(w io.Writer, signer *Entity, message io.Reader, config *packet.Config) error {
39
+	return detachSign(w, signer, message, packet.SigTypeText, config)
40
+}
41
+
42
+// ArmoredDetachSignText signs message (after canonicalising the line endings)
43
+// with the private key from signer (which must already have been decrypted)
44
+// and writes an armored signature to w.
45
+// If config is nil, sensible defaults will be used.
46
+func ArmoredDetachSignText(w io.Writer, signer *Entity, message io.Reader, config *packet.Config) error {
47
+	return armoredDetachSign(w, signer, message, packet.SigTypeText, config)
48
+}
49
+
50
+func armoredDetachSign(w io.Writer, signer *Entity, message io.Reader, sigType packet.SignatureType, config *packet.Config) (err error) {
51
+	out, err := armor.Encode(w, SignatureType, nil)
52
+	if err != nil {
53
+		return
54
+	}
55
+	err = detachSign(out, signer, message, sigType, config)
56
+	if err != nil {
57
+		return
58
+	}
59
+	return out.Close()
60
+}
61
+
62
+func detachSign(w io.Writer, signer *Entity, message io.Reader, sigType packet.SignatureType, config *packet.Config) (err error) {
63
+	if signer.PrivateKey == nil {
64
+		return errors.InvalidArgumentError("signing key doesn't have a private key")
65
+	}
66
+	if signer.PrivateKey.Encrypted {
67
+		return errors.InvalidArgumentError("signing key is encrypted")
68
+	}
69
+
70
+	sig := new(packet.Signature)
71
+	sig.SigType = sigType
72
+	sig.PubKeyAlgo = signer.PrivateKey.PubKeyAlgo
73
+	sig.Hash = config.Hash()
74
+	sig.CreationTime = config.Now()
75
+	sig.IssuerKeyId = &signer.PrivateKey.KeyId
76
+
77
+	h, wrappedHash, err := hashForSignature(sig.Hash, sig.SigType)
78
+	if err != nil {
79
+		return
80
+	}
81
+	io.Copy(wrappedHash, message)
82
+
83
+	err = sig.Sign(h, signer.PrivateKey, config)
84
+	if err != nil {
85
+		return
86
+	}
87
+
88
+	return sig.Serialize(w)
89
+}
90
+
91
+// FileHints contains metadata about encrypted files. This metadata is, itself,
92
+// encrypted.
93
+type FileHints struct {
94
+	// IsBinary can be set to hint that the contents are binary data.
95
+	IsBinary bool
96
+	// FileName hints at the name of the file that should be written. It's
97
+	// truncated to 255 bytes if longer. It may be empty to suggest that the
98
+	// file should not be written to disk. It may be equal to "_CONSOLE" to
99
+	// suggest the data should not be written to disk.
100
+	FileName string
101
+	// ModTime contains the modification time of the file, or the zero time if not applicable.
102
+	ModTime time.Time
103
+}
104
+
105
+// SymmetricallyEncrypt acts like gpg -c: it encrypts a file with a passphrase.
106
+// The resulting WriteCloser must be closed after the contents of the file have
107
+// been written.
108
+// If config is nil, sensible defaults will be used.
109
+func SymmetricallyEncrypt(ciphertext io.Writer, passphrase []byte, hints *FileHints, config *packet.Config) (plaintext io.WriteCloser, err error) {
110
+	if hints == nil {
111
+		hints = &FileHints{}
112
+	}
113
+
114
+	key, err := packet.SerializeSymmetricKeyEncrypted(ciphertext, passphrase, config)
115
+	if err != nil {
116
+		return
117
+	}
118
+	w, err := packet.SerializeSymmetricallyEncrypted(ciphertext, config.Cipher(), key, config)
119
+	if err != nil {
120
+		return
121
+	}
122
+
123
+	literaldata := w
124
+	if algo := config.Compression(); algo != packet.CompressionNone {
125
+		var compConfig *packet.CompressionConfig
126
+		if config != nil {
127
+			compConfig = config.CompressionConfig
128
+		}
129
+		literaldata, err = packet.SerializeCompressed(w, algo, compConfig)
130
+		if err != nil {
131
+			return
132
+		}
133
+	}
134
+
135
+	var epochSeconds uint32
136
+	if !hints.ModTime.IsZero() {
137
+		epochSeconds = uint32(hints.ModTime.Unix())
138
+	}
139
+	return packet.SerializeLiteral(literaldata, hints.IsBinary, hints.FileName, epochSeconds)
140
+}
141
+
142
+// intersectPreferences mutates and returns a prefix of a that contains only
143
+// the values in the intersection of a and b. The order of a is preserved.
144
+func intersectPreferences(a []uint8, b []uint8) (intersection []uint8) {
145
+	var j int
146
+	for _, v := range a {
147
+		for _, v2 := range b {
148
+			if v == v2 {
149
+				a[j] = v
150
+				j++
151
+				break
152
+			}
153
+		}
154
+	}
155
+
156
+	return a[:j]
157
+}
158
+
159
+func hashToHashId(h crypto.Hash) uint8 {
160
+	v, ok := s2k.HashToHashId(h)
161
+	if !ok {
162
+		panic("tried to convert unknown hash")
163
+	}
164
+	return v
165
+}
166
+
167
+// Encrypt encrypts a message to a number of recipients and, optionally, signs
168
+// it. hints contains optional information, that is also encrypted, that aids
169
+// the recipients in processing the message. The resulting WriteCloser must
170
+// be closed after the contents of the file have been written.
171
+// If config is nil, sensible defaults will be used.
172
+func Encrypt(ciphertext io.Writer, to []*Entity, signed *Entity, hints *FileHints, config *packet.Config) (plaintext io.WriteCloser, err error) {
173
+	var signer *packet.PrivateKey
174
+	if signed != nil {
175
+		signKey, ok := signed.signingKey(config.Now())
176
+		if !ok {
177
+			return nil, errors.InvalidArgumentError("no valid signing keys")
178
+		}
179
+		signer = signKey.PrivateKey
180
+		if signer == nil {
181
+			return nil, errors.InvalidArgumentError("no private key in signing key")
182
+		}
183
+		if signer.Encrypted {
184
+			return nil, errors.InvalidArgumentError("signing key must be decrypted")
185
+		}
186
+	}
187
+
188
+	// These are the possible ciphers that we'll use for the message.
189
+	candidateCiphers := []uint8{
190
+		uint8(packet.CipherAES128),
191
+		uint8(packet.CipherAES256),
192
+		uint8(packet.CipherCAST5),
193
+	}
194
+	// These are the possible hash functions that we'll use for the signature.
195
+	candidateHashes := []uint8{
196
+		hashToHashId(crypto.SHA256),
197
+		hashToHashId(crypto.SHA512),
198
+		hashToHashId(crypto.SHA1),
199
+		hashToHashId(crypto.RIPEMD160),
200
+	}
201
+	// In the event that a recipient doesn't specify any supported ciphers
202
+	// or hash functions, these are the ones that we assume that every
203
+	// implementation supports.
204
+	defaultCiphers := candidateCiphers[len(candidateCiphers)-1:]
205
+	defaultHashes := candidateHashes[len(candidateHashes)-1:]
206
+
207
+	encryptKeys := make([]Key, len(to))
208
+	for i := range to {
209
+		var ok bool
210
+		encryptKeys[i], ok = to[i].encryptionKey(config.Now())
211
+		if !ok {
212
+			return nil, errors.InvalidArgumentError("cannot encrypt a message to key id " + strconv.FormatUint(to[i].PrimaryKey.KeyId, 16) + " because it has no encryption keys")
213
+		}
214
+
215
+		sig := to[i].primaryIdentity().SelfSignature
216
+
217
+		preferredSymmetric := sig.PreferredSymmetric
218
+		if len(preferredSymmetric) == 0 {
219
+			preferredSymmetric = defaultCiphers
220
+		}
221
+		preferredHashes := sig.PreferredHash
222
+		if len(preferredHashes) == 0 {
223
+			preferredHashes = defaultHashes
224
+		}
225
+		candidateCiphers = intersectPreferences(candidateCiphers, preferredSymmetric)
226
+		candidateHashes = intersectPreferences(candidateHashes, preferredHashes)
227
+	}
228
+
229
+	if len(candidateCiphers) == 0 || len(candidateHashes) == 0 {
230
+		return nil, errors.InvalidArgumentError("cannot encrypt because recipient set shares no common algorithms")
231
+	}
232
+
233
+	cipher := packet.CipherFunction(candidateCiphers[0])
234
+	// If the cipher specified by config is a candidate, we'll use that.
235
+	configuredCipher := config.Cipher()
236
+	for _, c := range candidateCiphers {
237
+		cipherFunc := packet.CipherFunction(c)
238
+		if cipherFunc == configuredCipher {
239
+			cipher = cipherFunc
240
+			break
241
+		}
242
+	}
243
+
244
+	var hash crypto.Hash
245
+	for _, hashId := range candidateHashes {
246
+		if h, ok := s2k.HashIdToHash(hashId); ok && h.Available() {
247
+			hash = h
248
+			break
249
+		}
250
+	}
251
+
252
+	// If the hash specified by config is a candidate, we'll use that.
253
+	if configuredHash := config.Hash(); configuredHash.Available() {
254
+		for _, hashId := range candidateHashes {
255
+			if h, ok := s2k.HashIdToHash(hashId); ok && h == configuredHash {
256
+				hash = h
257
+				break
258
+			}
259
+		}
260
+	}
261
+
262
+	if hash == 0 {
263
+		hashId := candidateHashes[0]
264
+		name, ok := s2k.HashIdToString(hashId)
265
+		if !ok {
266
+			name = "#" + strconv.Itoa(int(hashId))
267
+		}
268
+		return nil, errors.InvalidArgumentError("cannot encrypt because no candidate hash functions are compiled in. (Wanted " + name + " in this case.)")
269
+	}
270
+
271
+	symKey := make([]byte, cipher.KeySize())
272
+	if _, err := io.ReadFull(config.Random(), symKey); err != nil {
273
+		return nil, err
274
+	}
275
+
276
+	for _, key := range encryptKeys {
277
+		if err := packet.SerializeEncryptedKey(ciphertext, key.PublicKey, cipher, symKey, config); err != nil {
278
+			return nil, err
279
+		}
280
+	}
281
+
282
+	encryptedData, err := packet.SerializeSymmetricallyEncrypted(ciphertext, cipher, symKey, config)
283
+	if err != nil {
284
+		return
285
+	}
286
+
287
+	if signer != nil {
288
+		ops := &packet.OnePassSignature{
289
+			SigType:    packet.SigTypeBinary,
290
+			Hash:       hash,
291
+			PubKeyAlgo: signer.PubKeyAlgo,
292
+			KeyId:      signer.KeyId,
293
+			IsLast:     true,
294
+		}
295
+		if err := ops.Serialize(encryptedData); err != nil {
296
+			return nil, err
297
+		}
298
+	}
299
+
300
+	if hints == nil {
301
+		hints = &FileHints{}
302
+	}
303
+
304
+	w := encryptedData
305
+	if signer != nil {
306
+		// If we need to write a signature packet after the literal
307
+		// data then we need to stop literalData from closing
308
+		// encryptedData.
309
+		w = noOpCloser{encryptedData}
310
+
311
+	}
312
+	var epochSeconds uint32
313
+	if !hints.ModTime.IsZero() {
314
+		epochSeconds = uint32(hints.ModTime.Unix())
315
+	}
316
+	literalData, err := packet.SerializeLiteral(w, hints.IsBinary, hints.FileName, epochSeconds)
317
+	if err != nil {
318
+		return nil, err
319
+	}
320
+
321
+	if signer != nil {
322
+		return signatureWriter{encryptedData, literalData, hash, hash.New(), signer, config}, nil
323
+	}
324
+	return literalData, nil
325
+}
326
+
327
+// signatureWriter hashes the contents of a message while passing it along to
328
+// literalData. When closed, it closes literalData, writes a signature packet
329
+// to encryptedData and then also closes encryptedData.
330
+type signatureWriter struct {
331
+	encryptedData io.WriteCloser
332
+	literalData   io.WriteCloser
333
+	hashType      crypto.Hash
334
+	h             hash.Hash
335
+	signer        *packet.PrivateKey
336
+	config        *packet.Config
337
+}
338
+
339
+func (s signatureWriter) Write(data []byte) (int, error) {
340
+	s.h.Write(data)
341
+	return s.literalData.Write(data)
342
+}
343
+
344
+func (s signatureWriter) Close() error {
345
+	sig := &packet.Signature{
346
+		SigType:      packet.SigTypeBinary,
347
+		PubKeyAlgo:   s.signer.PubKeyAlgo,
348
+		Hash:         s.hashType,
349
+		CreationTime: s.config.Now(),
350
+		IssuerKeyId:  &s.signer.KeyId,
351
+	}
352
+
353
+	if err := sig.Sign(s.h, s.signer, s.config); err != nil {
354
+		return err
355
+	}
356
+	if err := s.literalData.Close(); err != nil {
357
+		return err
358
+	}
359
+	if err := sig.Serialize(s.encryptedData); err != nil {
360
+		return err
361
+	}
362
+	return s.encryptedData.Close()
363
+}
364
+
365
+// noOpCloser is like an ioutil.NopCloser, but for an io.Writer.
366
+// TODO: we have two of these in OpenPGP packages alone. This probably needs
367
+// to be promoted somewhere more common.
368
+type noOpCloser struct {
369
+	w io.Writer
370
+}
371
+
372
+func (c noOpCloser) Write(data []byte) (n int, err error) {
373
+	return c.w.Write(data)
374
+}
375
+
376
+func (c noOpCloser) Close() error {
377
+	return nil
378
+}

+ 273
- 0
vendor/src/golang.org/x/crypto/openpgp/write_test.go 查看文件

@@ -0,0 +1,273 @@
1
+// Copyright 2011 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
+
5
+package openpgp
6
+
7
+import (
8
+	"bytes"
9
+	"io"
10
+	"io/ioutil"
11
+	"testing"
12
+	"time"
13
+
14
+	"golang.org/x/crypto/openpgp/packet"
15
+)
16
+
17
+func TestSignDetached(t *testing.T) {
18
+	kring, _ := ReadKeyRing(readerFromHex(testKeys1And2PrivateHex))
19
+	out := bytes.NewBuffer(nil)
20
+	message := bytes.NewBufferString(signedInput)
21
+	err := DetachSign(out, kring[0], message, nil)
22
+	if err != nil {
23
+		t.Error(err)
24
+	}
25
+
26
+	testDetachedSignature(t, kring, out, signedInput, "check", testKey1KeyId)
27
+}
28
+
29
+func TestSignTextDetached(t *testing.T) {
30
+	kring, _ := ReadKeyRing(readerFromHex(testKeys1And2PrivateHex))
31
+	out := bytes.NewBuffer(nil)
32
+	message := bytes.NewBufferString(signedInput)
33
+	err := DetachSignText(out, kring[0], message, nil)
34
+	if err != nil {
35
+		t.Error(err)
36
+	}
37
+
38
+	testDetachedSignature(t, kring, out, signedInput, "check", testKey1KeyId)
39
+}
40
+
41
+func TestSignDetachedDSA(t *testing.T) {
42
+	kring, _ := ReadKeyRing(readerFromHex(dsaTestKeyPrivateHex))
43
+	out := bytes.NewBuffer(nil)
44
+	message := bytes.NewBufferString(signedInput)
45
+	err := DetachSign(out, kring[0], message, nil)
46
+	if err != nil {
47
+		t.Error(err)
48
+	}
49
+
50
+	testDetachedSignature(t, kring, out, signedInput, "check", testKey3KeyId)
51
+}
52
+
53
+func TestSignDetachedP256(t *testing.T) {
54
+	kring, _ := ReadKeyRing(readerFromHex(p256TestKeyPrivateHex))
55
+	kring[0].PrivateKey.Decrypt([]byte("passphrase"))
56
+
57
+	out := bytes.NewBuffer(nil)
58
+	message := bytes.NewBufferString(signedInput)
59
+	err := DetachSign(out, kring[0], message, nil)
60
+	if err != nil {
61
+		t.Error(err)
62
+	}
63
+
64
+	testDetachedSignature(t, kring, out, signedInput, "check", testKeyP256KeyId)
65
+}
66
+
67
+func TestNewEntity(t *testing.T) {
68
+	if testing.Short() {
69
+		return
70
+	}
71
+
72
+	// Check bit-length with no config.
73
+	e, err := NewEntity("Test User", "test", "test@example.com", nil)
74
+	if err != nil {
75
+		t.Errorf("failed to create entity: %s", err)
76
+		return
77
+	}
78
+	bl, err := e.PrimaryKey.BitLength()
79
+	if err != nil {
80
+		t.Errorf("failed to find bit length: %s", err)
81
+	}
82
+	if int(bl) != defaultRSAKeyBits {
83
+		t.Errorf("BitLength %v, expected %v", int(bl), defaultRSAKeyBits)
84
+	}
85
+
86
+	// Check bit-length with a config.
87
+	cfg := &packet.Config{RSABits: 1024}
88
+	e, err = NewEntity("Test User", "test", "test@example.com", cfg)
89
+	if err != nil {
90
+		t.Errorf("failed to create entity: %s", err)
91
+		return
92
+	}
93
+	bl, err = e.PrimaryKey.BitLength()
94
+	if err != nil {
95
+		t.Errorf("failed to find bit length: %s", err)
96
+	}
97
+	if int(bl) != cfg.RSABits {
98
+		t.Errorf("BitLength %v, expected %v", bl, cfg.RSABits)
99
+	}
100
+
101
+	w := bytes.NewBuffer(nil)
102
+	if err := e.SerializePrivate(w, nil); err != nil {
103
+		t.Errorf("failed to serialize entity: %s", err)
104
+		return
105
+	}
106
+	serialized := w.Bytes()
107
+
108
+	el, err := ReadKeyRing(w)
109
+	if err != nil {
110
+		t.Errorf("failed to reparse entity: %s", err)
111
+		return
112
+	}
113
+
114
+	if len(el) != 1 {
115
+		t.Errorf("wrong number of entities found, got %d, want 1", len(el))
116
+	}
117
+
118
+	w = bytes.NewBuffer(nil)
119
+	if err := e.SerializePrivate(w, nil); err != nil {
120
+		t.Errorf("failed to serialize entity second time: %s", err)
121
+		return
122
+	}
123
+
124
+	if !bytes.Equal(w.Bytes(), serialized) {
125
+		t.Errorf("results differed")
126
+	}
127
+}
128
+
129
+func TestSymmetricEncryption(t *testing.T) {
130
+	buf := new(bytes.Buffer)
131
+	plaintext, err := SymmetricallyEncrypt(buf, []byte("testing"), nil, nil)
132
+	if err != nil {
133
+		t.Errorf("error writing headers: %s", err)
134
+		return
135
+	}
136
+	message := []byte("hello world\n")
137
+	_, err = plaintext.Write(message)
138
+	if err != nil {
139
+		t.Errorf("error writing to plaintext writer: %s", err)
140
+	}
141
+	err = plaintext.Close()
142
+	if err != nil {
143
+		t.Errorf("error closing plaintext writer: %s", err)
144
+	}
145
+
146
+	md, err := ReadMessage(buf, nil, func(keys []Key, symmetric bool) ([]byte, error) {
147
+		return []byte("testing"), nil
148
+	}, nil)
149
+	if err != nil {
150
+		t.Errorf("error rereading message: %s", err)
151
+	}
152
+	messageBuf := bytes.NewBuffer(nil)
153
+	_, err = io.Copy(messageBuf, md.UnverifiedBody)
154
+	if err != nil {
155
+		t.Errorf("error rereading message: %s", err)
156
+	}
157
+	if !bytes.Equal(message, messageBuf.Bytes()) {
158
+		t.Errorf("recovered message incorrect got '%s', want '%s'", messageBuf.Bytes(), message)
159
+	}
160
+}
161
+
162
+var testEncryptionTests = []struct {
163
+	keyRingHex string
164
+	isSigned   bool
165
+}{
166
+	{
167
+		testKeys1And2PrivateHex,
168
+		false,
169
+	},
170
+	{
171
+		testKeys1And2PrivateHex,
172
+		true,
173
+	},
174
+	{
175
+		dsaElGamalTestKeysHex,
176
+		false,
177
+	},
178
+	{
179
+		dsaElGamalTestKeysHex,
180
+		true,
181
+	},
182
+}
183
+
184
+func TestEncryption(t *testing.T) {
185
+	for i, test := range testEncryptionTests {
186
+		kring, _ := ReadKeyRing(readerFromHex(test.keyRingHex))
187
+
188
+		passphrase := []byte("passphrase")
189
+		for _, entity := range kring {
190
+			if entity.PrivateKey != nil && entity.PrivateKey.Encrypted {
191
+				err := entity.PrivateKey.Decrypt(passphrase)
192
+				if err != nil {
193
+					t.Errorf("#%d: failed to decrypt key", i)
194
+				}
195
+			}
196
+			for _, subkey := range entity.Subkeys {
197
+				if subkey.PrivateKey != nil && subkey.PrivateKey.Encrypted {
198
+					err := subkey.PrivateKey.Decrypt(passphrase)
199
+					if err != nil {
200
+						t.Errorf("#%d: failed to decrypt subkey", i)
201
+					}
202
+				}
203
+			}
204
+		}
205
+
206
+		var signed *Entity
207
+		if test.isSigned {
208
+			signed = kring[0]
209
+		}
210
+
211
+		buf := new(bytes.Buffer)
212
+		w, err := Encrypt(buf, kring[:1], signed, nil /* no hints */, nil)
213
+		if err != nil {
214
+			t.Errorf("#%d: error in Encrypt: %s", i, err)
215
+			continue
216
+		}
217
+
218
+		const message = "testing"
219
+		_, err = w.Write([]byte(message))
220
+		if err != nil {
221
+			t.Errorf("#%d: error writing plaintext: %s", i, err)
222
+			continue
223
+		}
224
+		err = w.Close()
225
+		if err != nil {
226
+			t.Errorf("#%d: error closing WriteCloser: %s", i, err)
227
+			continue
228
+		}
229
+
230
+		md, err := ReadMessage(buf, kring, nil /* no prompt */, nil)
231
+		if err != nil {
232
+			t.Errorf("#%d: error reading message: %s", i, err)
233
+			continue
234
+		}
235
+
236
+		testTime, _ := time.Parse("2006-01-02", "2013-07-01")
237
+		if test.isSigned {
238
+			signKey, _ := kring[0].signingKey(testTime)
239
+			expectedKeyId := signKey.PublicKey.KeyId
240
+			if md.SignedByKeyId != expectedKeyId {
241
+				t.Errorf("#%d: message signed by wrong key id, got: %v, want: %v", i, *md.SignedBy, expectedKeyId)
242
+			}
243
+			if md.SignedBy == nil {
244
+				t.Errorf("#%d: failed to find the signing Entity", i)
245
+			}
246
+		}
247
+
248
+		plaintext, err := ioutil.ReadAll(md.UnverifiedBody)
249
+		if err != nil {
250
+			t.Errorf("#%d: error reading encrypted contents: %s", i, err)
251
+			continue
252
+		}
253
+
254
+		encryptKey, _ := kring[0].encryptionKey(testTime)
255
+		expectedKeyId := encryptKey.PublicKey.KeyId
256
+		if len(md.EncryptedToKeyIds) != 1 || md.EncryptedToKeyIds[0] != expectedKeyId {
257
+			t.Errorf("#%d: expected message to be encrypted to %v, but got %#v", i, expectedKeyId, md.EncryptedToKeyIds)
258
+		}
259
+
260
+		if string(plaintext) != message {
261
+			t.Errorf("#%d: got: %s, want: %s", i, string(plaintext), message)
262
+		}
263
+
264
+		if test.isSigned {
265
+			if md.SignatureError != nil {
266
+				t.Errorf("#%d: signature error: %s", i, md.SignatureError)
267
+			}
268
+			if md.Signature == nil {
269
+				t.Error("signature missing")
270
+			}
271
+		}
272
+	}
273
+}

+ 3
- 0
vendor/src/gopkg.in/src-d/go-git-fixtures.v3/README.md 查看文件

@@ -0,0 +1,3 @@
1
+# go-git-fixtures
2
+
3
+git repository fixtures being use by [go-git](https://github.com/src-d/go-git)

二进制
vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/git-0a00a25543e6d732dbf4e8e9fec55c8e65fc4e8d.tgz 查看文件


二进制
vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/git-174be6bd4292c18160542ae6dc6704b877b8a01a.tgz 查看文件


二进制
vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/git-21504f6d2cc2ef0c9d6ebb8802c7b49abae40c1a.tgz 查看文件


二进制
vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/git-4870d54b5b04e43da8cf99ceec179d9675494af8.tgz 查看文件


二进制
vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/git-4e7600af05c3356e8b142263e127b76f010facfc.tgz 查看文件


二进制
vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/git-78c5fb882e76286d8201016cffee63ea7060a0c2.tgz 查看文件


二进制
vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/git-7a725350b88b05ca03541b59dd0649fda7f521f2.tgz 查看文件


二进制
vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/git-7cbde0ca02f13aedd5ec8b358ca17b1c0bf5ee64.tgz 查看文件


二进制
vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/git-935e5ac17c41c309c356639816ea0694a568c484.tgz 查看文件


二进制
vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/git-bf3fedcc8e20fd0dec9172987ceea0038d17b516.tgz 查看文件


二进制
vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/git-c0c7c57ab1753ddbd26cc45322299ddd12842794.tgz 查看文件


二进制
vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/git-df6781fd40b8f4911d70ce71f8387b991615cd6d.tgz 查看文件


二进制
vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/git-e1580a78f7d36791249df76df8a2a2613d629902.tgz 查看文件


二进制
vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/pack-0d3d824fb5c930e7e7e1f0f399f2976847d31fd3.idx 查看文件


二进制
vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/pack-0d3d824fb5c930e7e7e1f0f399f2976847d31fd3.pack 查看文件


二进制
vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/pack-0d9b6cfc261785837939aaede5986d7a7c212518.idx 查看文件


+ 0
- 0
vendor/src/gopkg.in/src-d/go-git-fixtures.v3/data/pack-0d9b6cfc261785837939aaede5986d7a7c212518.pack 查看文件


部分文件因为文件数量过多而无法显示