aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/golang.org
diff options
context:
space:
mode:
authorRadek Simko <radek.simko@gmail.com>2017-08-10 14:38:14 +0200
committerRadek Simko <radek.simko@gmail.com>2017-08-10 14:38:14 +0200
commitc680a8e1622ed0f18751d9d167c836ee24f5e897 (patch)
tree864f925049d422033dd25a73bafce32b361c8827 /vendor/golang.org
parent38f8880ac81bfabc6d7f82e4dc89661f20fc559e (diff)
downloadterraform-provider-statuscake-c680a8e1622ed0f18751d9d167c836ee24f5e897.tar.gz
terraform-provider-statuscake-c680a8e1622ed0f18751d9d167c836ee24f5e897.tar.zst
terraform-provider-statuscake-c680a8e1622ed0f18751d9d167c836ee24f5e897.zip
vendor: github.com/hashicorp/terraform/...@v0.10.0
Diffstat (limited to 'vendor/golang.org')
-rw-r--r--vendor/golang.org/x/crypto/cast5/cast5.go526
-rw-r--r--vendor/golang.org/x/crypto/openpgp/armor/armor.go219
-rw-r--r--vendor/golang.org/x/crypto/openpgp/armor/encode.go160
-rw-r--r--vendor/golang.org/x/crypto/openpgp/canonical_text.go59
-rw-r--r--vendor/golang.org/x/crypto/openpgp/elgamal/elgamal.go122
-rw-r--r--vendor/golang.org/x/crypto/openpgp/errors/errors.go72
-rw-r--r--vendor/golang.org/x/crypto/openpgp/keys.go637
-rw-r--r--vendor/golang.org/x/crypto/openpgp/packet/compressed.go123
-rw-r--r--vendor/golang.org/x/crypto/openpgp/packet/config.go91
-rw-r--r--vendor/golang.org/x/crypto/openpgp/packet/encrypted_key.go199
-rw-r--r--vendor/golang.org/x/crypto/openpgp/packet/literal.go89
-rw-r--r--vendor/golang.org/x/crypto/openpgp/packet/ocfb.go143
-rw-r--r--vendor/golang.org/x/crypto/openpgp/packet/one_pass_signature.go73
-rw-r--r--vendor/golang.org/x/crypto/openpgp/packet/opaque.go162
-rw-r--r--vendor/golang.org/x/crypto/openpgp/packet/packet.go537
-rw-r--r--vendor/golang.org/x/crypto/openpgp/packet/private_key.go380
-rw-r--r--vendor/golang.org/x/crypto/openpgp/packet/public_key.go748
-rw-r--r--vendor/golang.org/x/crypto/openpgp/packet/public_key_v3.go279
-rw-r--r--vendor/golang.org/x/crypto/openpgp/packet/reader.go76
-rw-r--r--vendor/golang.org/x/crypto/openpgp/packet/signature.go731
-rw-r--r--vendor/golang.org/x/crypto/openpgp/packet/signature_v3.go146
-rw-r--r--vendor/golang.org/x/crypto/openpgp/packet/symmetric_key_encrypted.go155
-rw-r--r--vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted.go290
-rw-r--r--vendor/golang.org/x/crypto/openpgp/packet/userattribute.go91
-rw-r--r--vendor/golang.org/x/crypto/openpgp/packet/userid.go160
-rw-r--r--vendor/golang.org/x/crypto/openpgp/read.go442
-rw-r--r--vendor/golang.org/x/crypto/openpgp/s2k/s2k.go273
-rw-r--r--vendor/golang.org/x/crypto/openpgp/write.go378
-rw-r--r--vendor/golang.org/x/net/LICENSE27
-rw-r--r--vendor/golang.org/x/net/PATENTS22
-rw-r--r--vendor/golang.org/x/net/html/atom/atom.go78
-rw-r--r--vendor/golang.org/x/net/html/atom/table.go713
-rw-r--r--vendor/golang.org/x/net/html/const.go102
-rw-r--r--vendor/golang.org/x/net/html/doc.go106
-rw-r--r--vendor/golang.org/x/net/html/doctype.go156
-rw-r--r--vendor/golang.org/x/net/html/entity.go2253
-rw-r--r--vendor/golang.org/x/net/html/escape.go258
-rw-r--r--vendor/golang.org/x/net/html/foreign.go226
-rw-r--r--vendor/golang.org/x/net/html/node.go193
-rw-r--r--vendor/golang.org/x/net/html/parse.go2094
-rw-r--r--vendor/golang.org/x/net/html/render.go271
-rw-r--r--vendor/golang.org/x/net/html/token.go1219
42 files changed, 15079 insertions, 0 deletions
diff --git a/vendor/golang.org/x/crypto/cast5/cast5.go b/vendor/golang.org/x/crypto/cast5/cast5.go
new file mode 100644
index 0000000..0b4af37
--- /dev/null
+++ b/vendor/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.
7package cast5 // import "golang.org/x/crypto/cast5"
8
9import "errors"
10
11const BlockSize = 8
12const KeySize = 16
13
14type Cipher struct {
15 masking [16]uint32
16 rotate [16]uint8
17}
18
19func 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
29func (c *Cipher) BlockSize() int {
30 return BlockSize
31}
32
33func (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
67func (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
101type keyScheduleA [4][7]uint8
102type 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
123type keyScheduleRound struct{}
124type keySchedule []keyScheduleRound
125
126var 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
188func (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.
235func 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
241func 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
247func 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
253var 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}
diff --git a/vendor/golang.org/x/crypto/openpgp/armor/armor.go b/vendor/golang.org/x/crypto/openpgp/armor/armor.go
new file mode 100644
index 0000000..592d186
--- /dev/null
+++ b/vendor/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.
7package armor // import "golang.org/x/crypto/openpgp/armor"
8
9import (
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.
30type 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
38var ArmorCorrupt error = errors.StructuralError("armor invalid")
39
40const crc24Init = 0xb704ce
41const crc24Poly = 0x1864cfb
42const crc24Mask = 0xffffff
43
44// crc24 calculates the OpenPGP checksum as specified in RFC 4880, section 6.1
45func 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
58var armorStart = []byte("-----BEGIN ")
59var armorEnd = []byte("-----END ")
60var 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.
64type lineReader struct {
65 in *bufio.Reader
66 buf []byte
67 eof bool
68 crc uint32
69}
70
71func (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.
134type openpgpReader struct {
135 lReader *lineReader
136 b64Reader io.Reader
137 currentCRC uint32
138}
139
140func (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.
157func Decode(in io.Reader) (p *Block, err error) {
158 r := bufio.NewReaderSize(in, 100)
159 var line []byte
160 ignoreNext := false
161
162TryNextBlock:
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}
diff --git a/vendor/golang.org/x/crypto/openpgp/armor/encode.go b/vendor/golang.org/x/crypto/openpgp/armor/encode.go
new file mode 100644
index 0000000..6f07582
--- /dev/null
+++ b/vendor/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
5package armor
6
7import (
8 "encoding/base64"
9 "io"
10)
11
12var armorHeaderSep = []byte(": ")
13var blockEnd = []byte("\n=")
14var newline = []byte("\n")
15var armorEndOfLineOut = []byte("-----\n")
16
17// writeSlices writes its arguments to the given Writer.
18func 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'.
30type lineBreaker struct {
31 lineLength int
32 line []byte
33 used int
34 out io.Writer
35 haveWritten bool
36}
37
38func 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
47func (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
83func (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
100type encoding struct {
101 out io.Writer
102 breaker *lineBreaker
103 b64 io.WriteCloser
104 crc uint32
105 blockType []byte
106}
107
108func (e *encoding) Write(data []byte) (n int, err error) {
109 e.crc = crc24(e.crc, data)
110 return e.b64.Write(data)
111}
112
113func (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.
133func 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}
diff --git a/vendor/golang.org/x/crypto/openpgp/canonical_text.go b/vendor/golang.org/x/crypto/openpgp/canonical_text.go
new file mode 100644
index 0000000..e601e38
--- /dev/null
+++ b/vendor/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
5package openpgp
6
7import "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.
11func NewCanonicalTextHash(h hash.Hash) hash.Hash {
12 return &canonicalTextHash{h, 0}
13}
14
15type canonicalTextHash struct {
16 h hash.Hash
17 s int
18}
19
20var newline = []byte{'\r', '\n'}
21
22func (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
44func (cth *canonicalTextHash) Sum(in []byte) []byte {
45 return cth.h.Sum(in)
46}
47
48func (cth *canonicalTextHash) Reset() {
49 cth.h.Reset()
50 cth.s = 0
51}
52
53func (cth *canonicalTextHash) Size() int {
54 return cth.h.Size()
55}
56
57func (cth *canonicalTextHash) BlockSize() int {
58 return cth.h.BlockSize()
59}
diff --git a/vendor/golang.org/x/crypto/openpgp/elgamal/elgamal.go b/vendor/golang.org/x/crypto/openpgp/elgamal/elgamal.go
new file mode 100644
index 0000000..73f4fe3
--- /dev/null
+++ b/vendor/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.
13package elgamal // import "golang.org/x/crypto/openpgp/elgamal"
14
15import (
16 "crypto/rand"
17 "crypto/subtle"
18 "errors"
19 "io"
20 "math/big"
21)
22
23// PublicKey represents an ElGamal public key.
24type PublicKey struct {
25 G, P, Y *big.Int
26}
27
28// PrivateKey represents an ElGamal private key.
29type 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.
37func 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),
77func 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.
106func 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}
diff --git a/vendor/golang.org/x/crypto/openpgp/errors/errors.go b/vendor/golang.org/x/crypto/openpgp/errors/errors.go
new file mode 100644
index 0000000..eb0550b
--- /dev/null
+++ b/vendor/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.
6package errors // import "golang.org/x/crypto/openpgp/errors"
7
8import (
9 "strconv"
10)
11
12// A StructuralError is returned when OpenPGP data is found to be syntactically
13// invalid.
14type StructuralError string
15
16func (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.
22type UnsupportedError string
23
24func (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.
30type InvalidArgumentError string
31
32func (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.
38type SignatureError string
39
40func (b SignatureError) Error() string {
41 return "openpgp: invalid signature: " + string(b)
42}
43
44type keyIncorrectError int
45
46func (ki keyIncorrectError) Error() string {
47 return "openpgp: incorrect key"
48}
49
50var ErrKeyIncorrect error = keyIncorrectError(0)
51
52type unknownIssuerError int
53
54func (unknownIssuerError) Error() string {
55 return "openpgp: signature made by unknown entity"
56}
57
58var ErrUnknownIssuer error = unknownIssuerError(0)
59
60type keyRevokedError int
61
62func (keyRevokedError) Error() string {
63 return "openpgp: signature made by revoked key"
64}
65
66var ErrKeyRevoked error = keyRevokedError(0)
67
68type UnknownPacketTypeError uint8
69
70func (upte UnknownPacketTypeError) Error() string {
71 return "openpgp: unknown packet type: " + strconv.Itoa(int(upte))
72}
diff --git a/vendor/golang.org/x/crypto/openpgp/keys.go b/vendor/golang.org/x/crypto/openpgp/keys.go
new file mode 100644
index 0000000..68b14c6
--- /dev/null
+++ b/vendor/golang.org/x/crypto/openpgp/keys.go
@@ -0,0 +1,637 @@
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
5package openpgp
6
7import (
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.
18var PublicKeyType = "PGP PUBLIC KEY BLOCK"
19
20// PrivateKeyType is the armor type for a PGP private key.
21var 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.
26type 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.
36type 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.
45type 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.
53type 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.
61type 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.
76func (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.
91func (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.
129func (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.
159type EntityList []*Entity
160
161// KeysById returns the set of keys that have the given key id.
162func (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.
189func (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.
224func (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.
236func 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.
253func 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.
291func 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.
314func 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 } else {
329 e.PrimaryKey = &e.PrivateKey.PublicKey
330 }
331 }
332
333 if !e.PrimaryKey.PubKeyAlgo.CanSign() {
334 return nil, errors.StructuralError("primary key cannot be used for signatures")
335 }
336
337 var current *Identity
338 var revocations []*packet.Signature
339EachPacket:
340 for {
341 p, err := packets.Next()
342 if err == io.EOF {
343 break
344 } else if err != nil {
345 return nil, err
346 }
347
348 switch pkt := p.(type) {
349 case *packet.UserId:
350 current = new(Identity)
351 current.Name = pkt.Id
352 current.UserId = pkt
353 e.Identities[pkt.Id] = current
354
355 for {
356 p, err = packets.Next()
357 if err == io.EOF {
358 return nil, io.ErrUnexpectedEOF
359 } else if err != nil {
360 return nil, err
361 }
362
363 sig, ok := p.(*packet.Signature)
364 if !ok {
365 return nil, errors.StructuralError("user ID packet not followed by self-signature")
366 }
367
368 if (sig.SigType == packet.SigTypePositiveCert || sig.SigType == packet.SigTypeGenericCert) && sig.IssuerKeyId != nil && *sig.IssuerKeyId == e.PrimaryKey.KeyId {
369 if err = e.PrimaryKey.VerifyUserIdSignature(pkt.Id, e.PrimaryKey, sig); err != nil {
370 return nil, errors.StructuralError("user ID self-signature invalid: " + err.Error())
371 }
372 current.SelfSignature = sig
373 break
374 }
375 current.Signatures = append(current.Signatures, sig)
376 }
377 case *packet.Signature:
378 if pkt.SigType == packet.SigTypeKeyRevocation {
379 revocations = append(revocations, pkt)
380 } else if pkt.SigType == packet.SigTypeDirectSignature {
381 // TODO: RFC4880 5.2.1 permits signatures
382 // directly on keys (eg. to bind additional
383 // revocation keys).
384 } else if current == nil {
385 return nil, errors.StructuralError("signature packet found before user id packet")
386 } else {
387 current.Signatures = append(current.Signatures, pkt)
388 }
389 case *packet.PrivateKey:
390 if pkt.IsSubkey == false {
391 packets.Unread(p)
392 break EachPacket
393 }
394 err = addSubkey(e, packets, &pkt.PublicKey, pkt)
395 if err != nil {
396 return nil, err
397 }
398 case *packet.PublicKey:
399 if pkt.IsSubkey == false {
400 packets.Unread(p)
401 break EachPacket
402 }
403 err = addSubkey(e, packets, pkt, nil)
404 if err != nil {
405 return nil, err
406 }
407 default:
408 // we ignore unknown packets
409 }
410 }
411
412 if len(e.Identities) == 0 {
413 return nil, errors.StructuralError("entity without any identities")
414 }
415
416 for _, revocation := range revocations {
417 err = e.PrimaryKey.VerifyRevocationSignature(revocation)
418 if err == nil {
419 e.Revocations = append(e.Revocations, revocation)
420 } else {
421 // TODO: RFC 4880 5.2.3.15 defines revocation keys.
422 return nil, errors.StructuralError("revocation signature signed by alternate key")
423 }
424 }
425
426 return e, nil
427}
428
429func addSubkey(e *Entity, packets *packet.Reader, pub *packet.PublicKey, priv *packet.PrivateKey) error {
430 var subKey Subkey
431 subKey.PublicKey = pub
432 subKey.PrivateKey = priv
433 p, err := packets.Next()
434 if err == io.EOF {
435 return io.ErrUnexpectedEOF
436 }
437 if err != nil {
438 return errors.StructuralError("subkey signature invalid: " + err.Error())
439 }
440 var ok bool
441 subKey.Sig, ok = p.(*packet.Signature)
442 if !ok {
443 return errors.StructuralError("subkey packet not followed by signature")
444 }
445 if subKey.Sig.SigType != packet.SigTypeSubkeyBinding && subKey.Sig.SigType != packet.SigTypeSubkeyRevocation {
446 return errors.StructuralError("subkey signature with wrong type")
447 }
448 err = e.PrimaryKey.VerifyKeySignature(subKey.PublicKey, subKey.Sig)
449 if err != nil {
450 return errors.StructuralError("subkey signature invalid: " + err.Error())
451 }
452 e.Subkeys = append(e.Subkeys, subKey)
453 return nil
454}
455
456const defaultRSAKeyBits = 2048
457
458// NewEntity returns an Entity that contains a fresh RSA/RSA keypair with a
459// single identity composed of the given full name, comment and email, any of
460// which may be empty but must not contain any of "()<>\x00".
461// If config is nil, sensible defaults will be used.
462func NewEntity(name, comment, email string, config *packet.Config) (*Entity, error) {
463 currentTime := config.Now()
464
465 bits := defaultRSAKeyBits
466 if config != nil && config.RSABits != 0 {
467 bits = config.RSABits
468 }
469
470 uid := packet.NewUserId(name, comment, email)
471 if uid == nil {
472 return nil, errors.InvalidArgumentError("user id field contained invalid characters")
473 }
474 signingPriv, err := rsa.GenerateKey(config.Random(), bits)
475 if err != nil {
476 return nil, err
477 }
478 encryptingPriv, err := rsa.GenerateKey(config.Random(), bits)
479 if err != nil {
480 return nil, err
481 }
482
483 e := &Entity{
484 PrimaryKey: packet.NewRSAPublicKey(currentTime, &signingPriv.PublicKey),
485 PrivateKey: packet.NewRSAPrivateKey(currentTime, signingPriv),
486 Identities: make(map[string]*Identity),
487 }
488 isPrimaryId := true
489 e.Identities[uid.Id] = &Identity{
490 Name: uid.Name,
491 UserId: uid,
492 SelfSignature: &packet.Signature{
493 CreationTime: currentTime,
494 SigType: packet.SigTypePositiveCert,
495 PubKeyAlgo: packet.PubKeyAlgoRSA,
496 Hash: config.Hash(),
497 IsPrimaryId: &isPrimaryId,
498 FlagsValid: true,
499 FlagSign: true,
500 FlagCertify: true,
501 IssuerKeyId: &e.PrimaryKey.KeyId,
502 },
503 }
504
505 // If the user passes in a DefaultHash via packet.Config,
506 // set the PreferredHash for the SelfSignature.
507 if config != nil && config.DefaultHash != 0 {
508 e.Identities[uid.Id].SelfSignature.PreferredHash = []uint8{hashToHashId(config.DefaultHash)}
509 }
510
511 e.Subkeys = make([]Subkey, 1)
512 e.Subkeys[0] = Subkey{
513 PublicKey: packet.NewRSAPublicKey(currentTime, &encryptingPriv.PublicKey),
514 PrivateKey: packet.NewRSAPrivateKey(currentTime, encryptingPriv),
515 Sig: &packet.Signature{
516 CreationTime: currentTime,
517 SigType: packet.SigTypeSubkeyBinding,
518 PubKeyAlgo: packet.PubKeyAlgoRSA,
519 Hash: config.Hash(),
520 FlagsValid: true,
521 FlagEncryptStorage: true,
522 FlagEncryptCommunications: true,
523 IssuerKeyId: &e.PrimaryKey.KeyId,
524 },
525 }
526 e.Subkeys[0].PublicKey.IsSubkey = true
527 e.Subkeys[0].PrivateKey.IsSubkey = true
528
529 return e, nil
530}
531
532// SerializePrivate serializes an Entity, including private key material, to
533// the given Writer. For now, it must only be used on an Entity returned from
534// NewEntity.
535// If config is nil, sensible defaults will be used.
536func (e *Entity) SerializePrivate(w io.Writer, config *packet.Config) (err error) {
537 err = e.PrivateKey.Serialize(w)
538 if err != nil {
539 return
540 }
541 for _, ident := range e.Identities {
542 err = ident.UserId.Serialize(w)
543 if err != nil {
544 return
545 }
546 err = ident.SelfSignature.SignUserId(ident.UserId.Id, e.PrimaryKey, e.PrivateKey, config)
547 if err != nil {
548 return
549 }
550 err = ident.SelfSignature.Serialize(w)
551 if err != nil {
552 return
553 }
554 }
555 for _, subkey := range e.Subkeys {
556 err = subkey.PrivateKey.Serialize(w)
557 if err != nil {
558 return
559 }
560 err = subkey.Sig.SignKey(subkey.PublicKey, e.PrivateKey, config)
561 if err != nil {
562 return
563 }
564 err = subkey.Sig.Serialize(w)
565 if err != nil {
566 return
567 }
568 }
569 return nil
570}
571
572// Serialize writes the public part of the given Entity to w. (No private
573// key material will be output).
574func (e *Entity) Serialize(w io.Writer) error {
575 err := e.PrimaryKey.Serialize(w)
576 if err != nil {
577 return err
578 }
579 for _, ident := range e.Identities {
580 err = ident.UserId.Serialize(w)
581 if err != nil {
582 return err
583 }
584 err = ident.SelfSignature.Serialize(w)
585 if err != nil {
586 return err
587 }
588 for _, sig := range ident.Signatures {
589 err = sig.Serialize(w)
590 if err != nil {
591 return err
592 }
593 }
594 }
595 for _, subkey := range e.Subkeys {
596 err = subkey.PublicKey.Serialize(w)
597 if err != nil {
598 return err
599 }
600 err = subkey.Sig.Serialize(w)
601 if err != nil {
602 return err
603 }
604 }
605 return nil
606}
607
608// SignIdentity adds a signature to e, from signer, attesting that identity is
609// associated with e. The provided identity must already be an element of
610// e.Identities and the private key of signer must have been decrypted if
611// necessary.
612// If config is nil, sensible defaults will be used.
613func (e *Entity) SignIdentity(identity string, signer *Entity, config *packet.Config) error {
614 if signer.PrivateKey == nil {
615 return errors.InvalidArgumentError("signing Entity must have a private key")
616 }
617 if signer.PrivateKey.Encrypted {
618 return errors.InvalidArgumentError("signing Entity's private key must be decrypted")
619 }
620 ident, ok := e.Identities[identity]
621 if !ok {
622 return errors.InvalidArgumentError("given identity string not found in Entity")
623 }
624
625 sig := &packet.Signature{
626 SigType: packet.SigTypeGenericCert,
627 PubKeyAlgo: signer.PrivateKey.PubKeyAlgo,
628 Hash: config.Hash(),
629 CreationTime: config.Now(),
630 IssuerKeyId: &signer.PrivateKey.KeyId,
631 }
632 if err := sig.SignUserId(identity, e.PrimaryKey, signer.PrivateKey, config); err != nil {
633 return err
634 }
635 ident.Signatures = append(ident.Signatures, sig)
636 return nil
637}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/compressed.go b/vendor/golang.org/x/crypto/openpgp/packet/compressed.go
new file mode 100644
index 0000000..e8f0b5c
--- /dev/null
+++ b/vendor/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
5package packet
6
7import (
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.
18type Compressed struct {
19 Body io.Reader
20}
21
22const (
23 NoCompression = flate.NoCompression
24 BestSpeed = flate.BestSpeed
25 BestCompression = flate.BestCompression
26 DefaultCompression = flate.DefaultCompression
27)
28
29// CompressionConfig contains compressor configuration settings.
30type 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
42func (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.
67type compressedWriteCloser struct {
68 sh io.Closer // Stream Header
69 c io.WriteCloser // Compressor
70}
71
72func (cwc compressedWriteCloser) Write(p []byte) (int, error) {
73 return cwc.c.Write(p)
74}
75
76func (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.
90func 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}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/config.go b/vendor/golang.org/x/crypto/openpgp/packet/config.go
new file mode 100644
index 0000000..c76eecc
--- /dev/null
+++ b/vendor/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
5package packet
6
7import (
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.
16type 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
51func (c *Config) Random() io.Reader {
52 if c == nil || c.Rand == nil {
53 return rand.Reader
54 }
55 return c.Rand
56}
57
58func (c *Config) Hash() crypto.Hash {
59 if c == nil || uint(c.DefaultHash) == 0 {
60 return crypto.SHA256
61 }
62 return c.DefaultHash
63}
64
65func (c *Config) Cipher() CipherFunction {
66 if c == nil || uint8(c.DefaultCipher) == 0 {
67 return CipherAES128
68 }
69 return c.DefaultCipher
70}
71
72func (c *Config) Now() time.Time {
73 if c == nil || c.Time == nil {
74 return time.Now()
75 }
76 return c.Time()
77}
78
79func (c *Config) Compression() CompressionAlgo {
80 if c == nil {
81 return CompressionNone
82 }
83 return c.DefaultCompressionAlgo
84}
85
86func (c *Config) PasswordHashIterations() int {
87 if c == nil || c.S2KCount == 0 {
88 return 0
89 }
90 return c.S2KCount
91}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/encrypted_key.go b/vendor/golang.org/x/crypto/openpgp/packet/encrypted_key.go
new file mode 100644
index 0000000..266840d
--- /dev/null
+++ b/vendor/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
5package packet
6
7import (
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
18const encryptedKeyVersion = 3
19
20// EncryptedKey represents a public-key encrypted session key. See RFC 4880,
21// section 5.1.
22type 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
31func (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
56func 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.
67func (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.
100func (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.
132func 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
157func 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
176func 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}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/literal.go b/vendor/golang.org/x/crypto/openpgp/packet/literal.go
new file mode 100644
index 0000000..1a9ec6e
--- /dev/null
+++ b/vendor/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
5package packet
6
7import (
8 "encoding/binary"
9 "io"
10)
11
12// LiteralData represents an encrypted file. See RFC 4880, section 5.9.
13type 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.
22func (l *LiteralData) ForEyesOnly() bool {
23 return l.FileName == "_CONSOLE"
24}
25
26func (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.
57func 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}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/ocfb.go b/vendor/golang.org/x/crypto/openpgp/packet/ocfb.go
new file mode 100644
index 0000000..ce2a33a
--- /dev/null
+++ b/vendor/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
7package packet
8
9import (
10 "crypto/cipher"
11)
12
13type 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.
21type OCFBResyncOption bool
22
23const (
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.
34func 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
66func (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
79type 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.
92func 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
131func (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}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/one_pass_signature.go b/vendor/golang.org/x/crypto/openpgp/packet/one_pass_signature.go
new file mode 100644
index 0000000..1713503
--- /dev/null
+++ b/vendor/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
5package packet
6
7import (
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.
18type OnePassSignature struct {
19 SigType SignatureType
20 Hash crypto.Hash
21 PubKeyAlgo PublicKeyAlgorithm
22 KeyId uint64
23 IsLast bool
24}
25
26const onePassSignatureVersion = 3
27
28func (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.
53func (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}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/opaque.go b/vendor/golang.org/x/crypto/openpgp/packet/opaque.go
new file mode 100644
index 0000000..456d807
--- /dev/null
+++ b/vendor/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
5package packet
6
7import (
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.
19type 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
28func (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.
35func (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.
46func (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.
62type OpaqueReader struct {
63 r io.Reader
64}
65
66func NewOpaqueReader(r io.Reader) *OpaqueReader {
67 return &OpaqueReader{r: r}
68}
69
70// Read the next OpaquePacket.
71func (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.
86type OpaqueSubpacket struct {
87 SubType uint8
88 Contents []byte
89}
90
91// OpaqueSubpackets extracts opaque, unparsed OpenPGP subpackets from
92// their byte representation.
93func 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
109func 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
148Truncated:
149 err = errors.StructuralError("subpacket truncated")
150 return
151}
152
153func (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}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/packet.go b/vendor/golang.org/x/crypto/openpgp/packet/packet.go
new file mode 100644
index 0000000..3eded93
--- /dev/null
+++ b/vendor/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.
7package packet // import "golang.org/x/crypto/openpgp/packet"
8
9import (
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.
22func 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.
31func 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.
66type partialLengthReader struct {
67 r io.Reader
68 remaining int64
69 isPartial bool
70}
71
72func (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.
98type partialLengthWriter struct {
99 w io.WriteCloser
100 lengthByte [1]byte
101}
102
103func (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
127func (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.
138type spanReader struct {
139 r io.Reader
140 n int64
141}
142
143func (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.
160func 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.
213func 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.
242func 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.
255type 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.
261func 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
280type packetType uint8
281
282const (
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.
302func 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.
314func 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.
383type SignatureType uint8
384
385const (
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
402type PublicKeyAlgorithm uint8
403
404const (
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.
417func (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.
427func (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
437type CipherFunction uint8
438
439const (
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.
448func (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.
465func (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.
478func (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.
493func 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.
508func 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.
515func 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.
524func 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.
531type CompressionAlgo uint8
532
533const (
534 CompressionNone CompressionAlgo = 0
535 CompressionZIP CompressionAlgo = 1
536 CompressionZLIB CompressionAlgo = 2
537)
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/private_key.go b/vendor/golang.org/x/crypto/openpgp/packet/private_key.go
new file mode 100644
index 0000000..34734cc
--- /dev/null
+++ b/vendor/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
5package packet
6
7import (
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.
28type 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
39func 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
46func 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
53func 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
60func 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.
69func 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
84func (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
143func mod64kHash(d []byte) uint16 {
144 var h uint16
145 for _, b := range d {
146 h += uint16(b)
147 }
148 return h
149}
150
151func (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
206func 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
222func serializeDSAPrivateKey(w io.Writer, priv *dsa.PrivateKey) error {
223 return writeBig(w, priv.X)
224}
225
226func serializeElGamalPrivateKey(w io.Writer, priv *elgamal.PrivateKey) error {
227 return writeBig(w, priv.X)
228}
229
230func 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.
235func (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
277func (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
291func (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
325func (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
344func (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
363func (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}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/public_key.go b/vendor/golang.org/x/crypto/openpgp/packet/public_key.go
new file mode 100644
index 0000000..ead2623
--- /dev/null
+++ b/vendor/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
5package packet
6
7import (
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
29var (
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
38const maxOIDLength = 8
39
40// ecdsaKey stores the algorithm-specific fields for ECDSA keys.
41// as defined in RFC 6637, Section 9.
42type 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.
50func 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
65func (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
73func (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
83func (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
101func (f *ecdsaKey) byteLen() int {
102 return 1 + len(f.oid) + 2 + len(f.p.bytes)
103}
104
105type kdfHashFunction byte
106type kdfAlgorithm byte
107
108// ecdhKdf stores key derivation function parameters
109// used for ECDH encryption. See RFC 6637, Section 9.
110type ecdhKdf struct {
111 KdfHash kdfHashFunction
112 KdfAlgo kdfAlgorithm
113}
114
115func (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
137func (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
148func (f *ecdhKdf) byteLen() int {
149 return 4
150}
151
152// PublicKey represents an OpenPGP public key. See RFC 4880, section 5.5.2.
153type 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.
170type signingKey interface {
171 SerializeSignaturePrefix(io.Writer)
172 serializeWithoutHeaders(io.Writer) error
173}
174
175func 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.
183func 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.
197func 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.
213func 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
227func 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
253func (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
300func (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.
311func (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.
339func (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.
368func (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.
393func (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
421func (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.
459func (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
493func (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.
499func (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.
547func (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.
591func 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.
607func (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
636func 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.
651func (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.
661func 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.
685func (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.
695func (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").
705func (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").
711func (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.
718type 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.
725func 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.
736func (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}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/public_key_v3.go b/vendor/golang.org/x/crypto/openpgp/packet/public_key_v3.go
new file mode 100644
index 0000000..5daf7b6
--- /dev/null
+++ b/vendor/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
5package packet
6
7import (
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.
26type 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."
41func 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
53func (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
79func (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.
90func (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.
119func (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
133func (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.
156func (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
184func (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.
190func (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.
223func (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.
233func (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.
243func 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").
260func (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").
266func (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.
271func (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}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/reader.go b/vendor/golang.org/x/crypto/openpgp/packet/reader.go
new file mode 100644
index 0000000..34bc7c6
--- /dev/null
+++ b/vendor/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
5package packet
6
7import (
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.
14type 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.
25const 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.
29func (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.
58func (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.
67func (r *Reader) Unread(p Packet) {
68 r.q = append(r.q, p)
69}
70
71func NewReader(r io.Reader) *Reader {
72 return &Reader{
73 q: nil,
74 readers: []io.Reader{r},
75 }
76}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/signature.go b/vendor/golang.org/x/crypto/openpgp/packet/signature.go
new file mode 100644
index 0000000..6ce0cbe
--- /dev/null
+++ b/vendor/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
5package packet
6
7import (
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
24const (
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.
33type 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
82func (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.
178func 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
193type signatureSubpacketType uint8
194
195const (
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.
211func 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
393Truncated:
394 err = errors.StructuralError("signature subpacket truncated")
395 return
396}
397
398// subpacketLengthLength returns the length, in bytes, of an encoded length value.
399func 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.
410func 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.
432func 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.
444func 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.
459func (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.
468func (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
495func (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.
511func (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.
563func 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.
578func (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.
589func (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.
599func (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.
663type 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
670func (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}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/signature_v3.go b/vendor/golang.org/x/crypto/openpgp/packet/signature_v3.go
new file mode 100644
index 0000000..6edff88
--- /dev/null
+++ b/vendor/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
5package packet
6
7import (
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.
23type 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
35func (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.
105func (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}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/symmetric_key_encrypted.go b/vendor/golang.org/x/crypto/openpgp/packet/symmetric_key_encrypted.go
new file mode 100644
index 0000000..744c2d2
--- /dev/null
+++ b/vendor/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
5package packet
6
7import (
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.
19const maxSessionKeySizeInBytes = 64
20
21// SymmetricKeyEncrypted represents a passphrase protected session key. See RFC
22// 4880, section 5.3.
23type SymmetricKeyEncrypted struct {
24 CipherFunc CipherFunction
25 s2k func(out, in []byte)
26 encryptedKey []byte
27}
28
29const symmetricKeyEncryptedVersion = 4
30
31func (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.
73func (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.
103func 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}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted.go b/vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted.go
new file mode 100644
index 0000000..6126030
--- /dev/null
+++ b/vendor/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
5package packet
6
7import (
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.
20type 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
26const symmetricallyEncryptedVersion = 1
27
28func (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.
47func (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.
91type seReader struct {
92 in io.Reader
93}
94
95func (ser seReader) Read(buf []byte) (int, error) {
96 return ser.in.Read(buf)
97}
98
99func (ser seReader) Close() error {
100 return nil
101}
102
103const 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.
109type 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
119func (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.
179const mdcPacketTagByte = byte(0x80) | 0x40 | 19
180
181func (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.
213type seMDCWriter struct {
214 w io.WriteCloser
215 h hash.Hash
216}
217
218func (w *seMDCWriter) Write(buf []byte) (n int, err error) {
219 w.h.Write(buf)
220 return w.w.Write(buf)
221}
222
223func (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.
240type noOpCloser struct {
241 w io.Writer
242}
243
244func (c noOpCloser) Write(data []byte) (n int, err error) {
245 return c.w.Write(data)
246}
247
248func (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.
256func 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}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/userattribute.go b/vendor/golang.org/x/crypto/openpgp/packet/userattribute.go
new file mode 100644
index 0000000..96a2b38
--- /dev/null
+++ b/vendor/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
5package packet
6
7import (
8 "bytes"
9 "image"
10 "image/jpeg"
11 "io"
12 "io/ioutil"
13)
14
15const 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.
21type UserAttribute struct {
22 Contents []*OpaqueSubpacket
23}
24
25// NewUserAttributePhoto creates a user attribute packet
26// containing the given images.
27func 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.
53func NewUserAttribute(contents ...*OpaqueSubpacket) *UserAttribute {
54 return &UserAttribute{Contents: contents}
55}
56
57func (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.
69func (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.
84func (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}
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/userid.go b/vendor/golang.org/x/crypto/openpgp/packet/userid.go
new file mode 100644
index 0000000..d6bea7d
--- /dev/null
+++ b/vendor/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
5package packet
6
7import (
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>"
16type 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
22func 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 '>'
34func 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
67func (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.
80func (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>".
91func 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}
diff --git a/vendor/golang.org/x/crypto/openpgp/read.go b/vendor/golang.org/x/crypto/openpgp/read.go
new file mode 100644
index 0000000..6ec664f
--- /dev/null
+++ b/vendor/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.
6package openpgp // import "golang.org/x/crypto/openpgp"
7
8import (
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.
21var SignatureType = "PGP SIGNATURE"
22
23// readArmored reads an armored block with the given type.
24func 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.
39type 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.
73type 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.
77type 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.
86func 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.
101ParsePackets:
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.
149FindKey:
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.
225func 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
234FindLiteralData:
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.
284func 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.
303type checkReader struct {
304 md *MessageDetails
305}
306
307func (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.
321type signatureCheckReader struct {
322 packets *packet.Reader
323 h, wrappedHash hash.Hash
324 md *MessageDetails
325}
326
327func (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.
363func 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.
435func 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}
diff --git a/vendor/golang.org/x/crypto/openpgp/s2k/s2k.go b/vendor/golang.org/x/crypto/openpgp/s2k/s2k.go
new file mode 100644
index 0000000..4b9a44c
--- /dev/null
+++ b/vendor/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.
7package s2k // import "golang.org/x/crypto/openpgp/s2k"
8
9import (
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.
22type 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
39func (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
48func (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.
70func 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.
87func 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.
93func Simple(out []byte, h hash.Hash, in []byte) {
94 Salted(out, h, in, nil)
95}
96
97var 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.
101func 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.
121func 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.
156func 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.
207func 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.
228var 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.
244func 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.
255func 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.
266func 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}
diff --git a/vendor/golang.org/x/crypto/openpgp/write.go b/vendor/golang.org/x/crypto/openpgp/write.go
new file mode 100644
index 0000000..65a304c
--- /dev/null
+++ b/vendor/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
5package openpgp
6
7import (
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.
23func 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.
30func 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.
38func 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.
46func ArmoredDetachSignText(w io.Writer, signer *Entity, message io.Reader, config *packet.Config) error {
47 return armoredDetachSign(w, signer, message, packet.SigTypeText, config)
48}
49
50func 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
62func 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.
93type 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.
109func 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.
144func 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
159func 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.
172func 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.
330type 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
339func (s signatureWriter) Write(data []byte) (int, error) {
340 s.h.Write(data)
341 return s.literalData.Write(data)
342}
343
344func (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.
368type noOpCloser struct {
369 w io.Writer
370}
371
372func (c noOpCloser) Write(data []byte) (n int, err error) {
373 return c.w.Write(data)
374}
375
376func (c noOpCloser) Close() error {
377 return nil
378}
diff --git a/vendor/golang.org/x/net/LICENSE b/vendor/golang.org/x/net/LICENSE
new file mode 100644
index 0000000..6a66aea
--- /dev/null
+++ b/vendor/golang.org/x/net/LICENSE
@@ -0,0 +1,27 @@
1Copyright (c) 2009 The Go Authors. All rights reserved.
2
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions are
5met:
6
7 * Redistributions of source code must retain the above copyright
8notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above
10copyright notice, this list of conditions and the following disclaimer
11in the documentation and/or other materials provided with the
12distribution.
13 * Neither the name of Google Inc. nor the names of its
14contributors may be used to endorse or promote products derived from
15this software without specific prior written permission.
16
17THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/golang.org/x/net/PATENTS b/vendor/golang.org/x/net/PATENTS
new file mode 100644
index 0000000..7330990
--- /dev/null
+++ b/vendor/golang.org/x/net/PATENTS
@@ -0,0 +1,22 @@
1Additional IP Rights Grant (Patents)
2
3"This implementation" means the copyrightable works distributed by
4Google as part of the Go project.
5
6Google hereby grants to You a perpetual, worldwide, non-exclusive,
7no-charge, royalty-free, irrevocable (except as stated in this section)
8patent license to make, have made, use, offer to sell, sell, import,
9transfer and otherwise run, modify and propagate the contents of this
10implementation of Go, where such license applies only to those patent
11claims, both currently owned or controlled by Google and acquired in
12the future, licensable by Google that are necessarily infringed by this
13implementation of Go. This grant does not include claims that would be
14infringed only as a consequence of further modification of this
15implementation. If you or your agent or exclusive licensee institute or
16order or agree to the institution of patent litigation against any
17entity (including a cross-claim or counterclaim in a lawsuit) alleging
18that this implementation of Go or any code incorporated within this
19implementation of Go constitutes direct or contributory patent
20infringement, or inducement of patent infringement, then any patent
21rights granted to you under this License for this implementation of Go
22shall terminate as of the date such litigation is filed.
diff --git a/vendor/golang.org/x/net/html/atom/atom.go b/vendor/golang.org/x/net/html/atom/atom.go
new file mode 100644
index 0000000..cd0a8ac
--- /dev/null
+++ b/vendor/golang.org/x/net/html/atom/atom.go
@@ -0,0 +1,78 @@
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 atom provides integer codes (also known as atoms) for a fixed set of
6// frequently occurring HTML strings: tag names and attribute keys such as "p"
7// and "id".
8//
9// Sharing an atom's name between all elements with the same tag can result in
10// fewer string allocations when tokenizing and parsing HTML. Integer
11// comparisons are also generally faster than string comparisons.
12//
13// The value of an atom's particular code is not guaranteed to stay the same
14// between versions of this package. Neither is any ordering guaranteed:
15// whether atom.H1 < atom.H2 may also change. The codes are not guaranteed to
16// be dense. The only guarantees are that e.g. looking up "div" will yield
17// atom.Div, calling atom.Div.String will return "div", and atom.Div != 0.
18package atom // import "golang.org/x/net/html/atom"
19
20// Atom is an integer code for a string. The zero value maps to "".
21type Atom uint32
22
23// String returns the atom's name.
24func (a Atom) String() string {
25 start := uint32(a >> 8)
26 n := uint32(a & 0xff)
27 if start+n > uint32(len(atomText)) {
28 return ""
29 }
30 return atomText[start : start+n]
31}
32
33func (a Atom) string() string {
34 return atomText[a>>8 : a>>8+a&0xff]
35}
36
37// fnv computes the FNV hash with an arbitrary starting value h.
38func fnv(h uint32, s []byte) uint32 {
39 for i := range s {
40 h ^= uint32(s[i])
41 h *= 16777619
42 }
43 return h
44}
45
46func match(s string, t []byte) bool {
47 for i, c := range t {
48 if s[i] != c {
49 return false
50 }
51 }
52 return true
53}
54
55// Lookup returns the atom whose name is s. It returns zero if there is no
56// such atom. The lookup is case sensitive.
57func Lookup(s []byte) Atom {
58 if len(s) == 0 || len(s) > maxAtomLen {
59 return 0
60 }
61 h := fnv(hash0, s)
62 if a := table[h&uint32(len(table)-1)]; int(a&0xff) == len(s) && match(a.string(), s) {
63 return a
64 }
65 if a := table[(h>>16)&uint32(len(table)-1)]; int(a&0xff) == len(s) && match(a.string(), s) {
66 return a
67 }
68 return 0
69}
70
71// String returns a string whose contents are equal to s. In that sense, it is
72// equivalent to string(s) but may be more efficient.
73func String(s []byte) string {
74 if a := Lookup(s); a != 0 {
75 return a.String()
76 }
77 return string(s)
78}
diff --git a/vendor/golang.org/x/net/html/atom/table.go b/vendor/golang.org/x/net/html/atom/table.go
new file mode 100644
index 0000000..2605ba3
--- /dev/null
+++ b/vendor/golang.org/x/net/html/atom/table.go
@@ -0,0 +1,713 @@
1// generated by go run gen.go; DO NOT EDIT
2
3package atom
4
5const (
6 A Atom = 0x1
7 Abbr Atom = 0x4
8 Accept Atom = 0x2106
9 AcceptCharset Atom = 0x210e
10 Accesskey Atom = 0x3309
11 Action Atom = 0x1f606
12 Address Atom = 0x4f307
13 Align Atom = 0x1105
14 Alt Atom = 0x4503
15 Annotation Atom = 0x1670a
16 AnnotationXml Atom = 0x1670e
17 Applet Atom = 0x2b306
18 Area Atom = 0x2fa04
19 Article Atom = 0x38807
20 Aside Atom = 0x8305
21 Async Atom = 0x7b05
22 Audio Atom = 0xa605
23 Autocomplete Atom = 0x1fc0c
24 Autofocus Atom = 0xb309
25 Autoplay Atom = 0xce08
26 B Atom = 0x101
27 Base Atom = 0xd604
28 Basefont Atom = 0xd608
29 Bdi Atom = 0x1a03
30 Bdo Atom = 0xe703
31 Bgsound Atom = 0x11807
32 Big Atom = 0x12403
33 Blink Atom = 0x12705
34 Blockquote Atom = 0x12c0a
35 Body Atom = 0x2f04
36 Br Atom = 0x202
37 Button Atom = 0x13606
38 Canvas Atom = 0x7f06
39 Caption Atom = 0x1bb07
40 Center Atom = 0x5b506
41 Challenge Atom = 0x21f09
42 Charset Atom = 0x2807
43 Checked Atom = 0x32807
44 Cite Atom = 0x3c804
45 Class Atom = 0x4de05
46 Code Atom = 0x14904
47 Col Atom = 0x15003
48 Colgroup Atom = 0x15008
49 Color Atom = 0x15d05
50 Cols Atom = 0x16204
51 Colspan Atom = 0x16207
52 Command Atom = 0x17507
53 Content Atom = 0x42307
54 Contenteditable Atom = 0x4230f
55 Contextmenu Atom = 0x3310b
56 Controls Atom = 0x18808
57 Coords Atom = 0x19406
58 Crossorigin Atom = 0x19f0b
59 Data Atom = 0x44a04
60 Datalist Atom = 0x44a08
61 Datetime Atom = 0x23c08
62 Dd Atom = 0x26702
63 Default Atom = 0x8607
64 Defer Atom = 0x14b05
65 Del Atom = 0x3ef03
66 Desc Atom = 0x4db04
67 Details Atom = 0x4807
68 Dfn Atom = 0x6103
69 Dialog Atom = 0x1b06
70 Dir Atom = 0x6903
71 Dirname Atom = 0x6907
72 Disabled Atom = 0x10c08
73 Div Atom = 0x11303
74 Dl Atom = 0x11e02
75 Download Atom = 0x40008
76 Draggable Atom = 0x17b09
77 Dropzone Atom = 0x39108
78 Dt Atom = 0x50902
79 Em Atom = 0x6502
80 Embed Atom = 0x6505
81 Enctype Atom = 0x21107
82 Face Atom = 0x5b304
83 Fieldset Atom = 0x1b008
84 Figcaption Atom = 0x1b80a
85 Figure Atom = 0x1cc06
86 Font Atom = 0xda04
87 Footer Atom = 0x8d06
88 For Atom = 0x1d803
89 ForeignObject Atom = 0x1d80d
90 Foreignobject Atom = 0x1e50d
91 Form Atom = 0x1f204
92 Formaction Atom = 0x1f20a
93 Formenctype Atom = 0x20d0b
94 Formmethod Atom = 0x2280a
95 Formnovalidate Atom = 0x2320e
96 Formtarget Atom = 0x2470a
97 Frame Atom = 0x9a05
98 Frameset Atom = 0x9a08
99 H1 Atom = 0x26e02
100 H2 Atom = 0x29402
101 H3 Atom = 0x2a702
102 H4 Atom = 0x2e902
103 H5 Atom = 0x2f302
104 H6 Atom = 0x50b02
105 Head Atom = 0x2d504
106 Header Atom = 0x2d506
107 Headers Atom = 0x2d507
108 Height Atom = 0x25106
109 Hgroup Atom = 0x25906
110 Hidden Atom = 0x26506
111 High Atom = 0x26b04
112 Hr Atom = 0x27002
113 Href Atom = 0x27004
114 Hreflang Atom = 0x27008
115 Html Atom = 0x25504
116 HttpEquiv Atom = 0x2780a
117 I Atom = 0x601
118 Icon Atom = 0x42204
119 Id Atom = 0x8502
120 Iframe Atom = 0x29606
121 Image Atom = 0x29c05
122 Img Atom = 0x2a103
123 Input Atom = 0x3e805
124 Inputmode Atom = 0x3e809
125 Ins Atom = 0x1a803
126 Isindex Atom = 0x2a907
127 Ismap Atom = 0x2b005
128 Itemid Atom = 0x33c06
129 Itemprop Atom = 0x3c908
130 Itemref Atom = 0x5ad07
131 Itemscope Atom = 0x2b909
132 Itemtype Atom = 0x2c308
133 Kbd Atom = 0x1903
134 Keygen Atom = 0x3906
135 Keytype Atom = 0x53707
136 Kind Atom = 0x10904
137 Label Atom = 0xf005
138 Lang Atom = 0x27404
139 Legend Atom = 0x18206
140 Li Atom = 0x1202
141 Link Atom = 0x12804
142 List Atom = 0x44e04
143 Listing Atom = 0x44e07
144 Loop Atom = 0xf404
145 Low Atom = 0x11f03
146 Malignmark Atom = 0x100a
147 Manifest Atom = 0x5f108
148 Map Atom = 0x2b203
149 Mark Atom = 0x1604
150 Marquee Atom = 0x2cb07
151 Math Atom = 0x2d204
152 Max Atom = 0x2e103
153 Maxlength Atom = 0x2e109
154 Media Atom = 0x6e05
155 Mediagroup Atom = 0x6e0a
156 Menu Atom = 0x33804
157 Menuitem Atom = 0x33808
158 Meta Atom = 0x45d04
159 Meter Atom = 0x24205
160 Method Atom = 0x22c06
161 Mglyph Atom = 0x2a206
162 Mi Atom = 0x2eb02
163 Min Atom = 0x2eb03
164 Minlength Atom = 0x2eb09
165 Mn Atom = 0x23502
166 Mo Atom = 0x3ed02
167 Ms Atom = 0x2bc02
168 Mtext Atom = 0x2f505
169 Multiple Atom = 0x30308
170 Muted Atom = 0x30b05
171 Name Atom = 0x6c04
172 Nav Atom = 0x3e03
173 Nobr Atom = 0x5704
174 Noembed Atom = 0x6307
175 Noframes Atom = 0x9808
176 Noscript Atom = 0x3d208
177 Novalidate Atom = 0x2360a
178 Object Atom = 0x1ec06
179 Ol Atom = 0xc902
180 Onabort Atom = 0x13a07
181 Onafterprint Atom = 0x1c00c
182 Onautocomplete Atom = 0x1fa0e
183 Onautocompleteerror Atom = 0x1fa13
184 Onbeforeprint Atom = 0x6040d
185 Onbeforeunload Atom = 0x4e70e
186 Onblur Atom = 0xaa06
187 Oncancel Atom = 0xe908
188 Oncanplay Atom = 0x28509
189 Oncanplaythrough Atom = 0x28510
190 Onchange Atom = 0x3a708
191 Onclick Atom = 0x31007
192 Onclose Atom = 0x31707
193 Oncontextmenu Atom = 0x32f0d
194 Oncuechange Atom = 0x3420b
195 Ondblclick Atom = 0x34d0a
196 Ondrag Atom = 0x35706
197 Ondragend Atom = 0x35709
198 Ondragenter Atom = 0x3600b
199 Ondragleave Atom = 0x36b0b
200 Ondragover Atom = 0x3760a
201 Ondragstart Atom = 0x3800b
202 Ondrop Atom = 0x38f06
203 Ondurationchange Atom = 0x39f10
204 Onemptied Atom = 0x39609
205 Onended Atom = 0x3af07
206 Onerror Atom = 0x3b607
207 Onfocus Atom = 0x3bd07
208 Onhashchange Atom = 0x3da0c
209 Oninput Atom = 0x3e607
210 Oninvalid Atom = 0x3f209
211 Onkeydown Atom = 0x3fb09
212 Onkeypress Atom = 0x4080a
213 Onkeyup Atom = 0x41807
214 Onlanguagechange Atom = 0x43210
215 Onload Atom = 0x44206
216 Onloadeddata Atom = 0x4420c
217 Onloadedmetadata Atom = 0x45510
218 Onloadstart Atom = 0x46b0b
219 Onmessage Atom = 0x47609
220 Onmousedown Atom = 0x47f0b
221 Onmousemove Atom = 0x48a0b
222 Onmouseout Atom = 0x4950a
223 Onmouseover Atom = 0x4a20b
224 Onmouseup Atom = 0x4ad09
225 Onmousewheel Atom = 0x4b60c
226 Onoffline Atom = 0x4c209
227 Ononline Atom = 0x4cb08
228 Onpagehide Atom = 0x4d30a
229 Onpageshow Atom = 0x4fe0a
230 Onpause Atom = 0x50d07
231 Onplay Atom = 0x51706
232 Onplaying Atom = 0x51709
233 Onpopstate Atom = 0x5200a
234 Onprogress Atom = 0x52a0a
235 Onratechange Atom = 0x53e0c
236 Onreset Atom = 0x54a07
237 Onresize Atom = 0x55108
238 Onscroll Atom = 0x55f08
239 Onseeked Atom = 0x56708
240 Onseeking Atom = 0x56f09
241 Onselect Atom = 0x57808
242 Onshow Atom = 0x58206
243 Onsort Atom = 0x58b06
244 Onstalled Atom = 0x59509
245 Onstorage Atom = 0x59e09
246 Onsubmit Atom = 0x5a708
247 Onsuspend Atom = 0x5bb09
248 Ontimeupdate Atom = 0xdb0c
249 Ontoggle Atom = 0x5c408
250 Onunload Atom = 0x5cc08
251 Onvolumechange Atom = 0x5d40e
252 Onwaiting Atom = 0x5e209
253 Open Atom = 0x3cf04
254 Optgroup Atom = 0xf608
255 Optimum Atom = 0x5eb07
256 Option Atom = 0x60006
257 Output Atom = 0x49c06
258 P Atom = 0xc01
259 Param Atom = 0xc05
260 Pattern Atom = 0x5107
261 Ping Atom = 0x7704
262 Placeholder Atom = 0xc30b
263 Plaintext Atom = 0xfd09
264 Poster Atom = 0x15706
265 Pre Atom = 0x25e03
266 Preload Atom = 0x25e07
267 Progress Atom = 0x52c08
268 Prompt Atom = 0x5fa06
269 Public Atom = 0x41e06
270 Q Atom = 0x13101
271 Radiogroup Atom = 0x30a
272 Readonly Atom = 0x2fb08
273 Rel Atom = 0x25f03
274 Required Atom = 0x1d008
275 Reversed Atom = 0x5a08
276 Rows Atom = 0x9204
277 Rowspan Atom = 0x9207
278 Rp Atom = 0x1c602
279 Rt Atom = 0x13f02
280 Ruby Atom = 0xaf04
281 S Atom = 0x2c01
282 Samp Atom = 0x4e04
283 Sandbox Atom = 0xbb07
284 Scope Atom = 0x2bd05
285 Scoped Atom = 0x2bd06
286 Script Atom = 0x3d406
287 Seamless Atom = 0x31c08
288 Section Atom = 0x4e207
289 Select Atom = 0x57a06
290 Selected Atom = 0x57a08
291 Shape Atom = 0x4f905
292 Size Atom = 0x55504
293 Sizes Atom = 0x55505
294 Small Atom = 0x18f05
295 Sortable Atom = 0x58d08
296 Sorted Atom = 0x19906
297 Source Atom = 0x1aa06
298 Spacer Atom = 0x2db06
299 Span Atom = 0x9504
300 Spellcheck Atom = 0x3230a
301 Src Atom = 0x3c303
302 Srcdoc Atom = 0x3c306
303 Srclang Atom = 0x41107
304 Start Atom = 0x38605
305 Step Atom = 0x5f704
306 Strike Atom = 0x53306
307 Strong Atom = 0x55906
308 Style Atom = 0x61105
309 Sub Atom = 0x5a903
310 Summary Atom = 0x61607
311 Sup Atom = 0x61d03
312 Svg Atom = 0x62003
313 System Atom = 0x62306
314 Tabindex Atom = 0x46308
315 Table Atom = 0x42d05
316 Target Atom = 0x24b06
317 Tbody Atom = 0x2e05
318 Td Atom = 0x4702
319 Template Atom = 0x62608
320 Textarea Atom = 0x2f608
321 Tfoot Atom = 0x8c05
322 Th Atom = 0x22e02
323 Thead Atom = 0x2d405
324 Time Atom = 0xdd04
325 Title Atom = 0xa105
326 Tr Atom = 0x10502
327 Track Atom = 0x10505
328 Translate Atom = 0x14009
329 Tt Atom = 0x5302
330 Type Atom = 0x21404
331 Typemustmatch Atom = 0x2140d
332 U Atom = 0xb01
333 Ul Atom = 0x8a02
334 Usemap Atom = 0x51106
335 Value Atom = 0x4005
336 Var Atom = 0x11503
337 Video Atom = 0x28105
338 Wbr Atom = 0x12103
339 Width Atom = 0x50705
340 Wrap Atom = 0x58704
341 Xmp Atom = 0xc103
342)
343
344const hash0 = 0xc17da63e
345
346const maxAtomLen = 19
347
348var table = [1 << 9]Atom{
349 0x1: 0x48a0b, // onmousemove
350 0x2: 0x5e209, // onwaiting
351 0x3: 0x1fa13, // onautocompleteerror
352 0x4: 0x5fa06, // prompt
353 0x7: 0x5eb07, // optimum
354 0x8: 0x1604, // mark
355 0xa: 0x5ad07, // itemref
356 0xb: 0x4fe0a, // onpageshow
357 0xc: 0x57a06, // select
358 0xd: 0x17b09, // draggable
359 0xe: 0x3e03, // nav
360 0xf: 0x17507, // command
361 0x11: 0xb01, // u
362 0x14: 0x2d507, // headers
363 0x15: 0x44a08, // datalist
364 0x17: 0x4e04, // samp
365 0x1a: 0x3fb09, // onkeydown
366 0x1b: 0x55f08, // onscroll
367 0x1c: 0x15003, // col
368 0x20: 0x3c908, // itemprop
369 0x21: 0x2780a, // http-equiv
370 0x22: 0x61d03, // sup
371 0x24: 0x1d008, // required
372 0x2b: 0x25e07, // preload
373 0x2c: 0x6040d, // onbeforeprint
374 0x2d: 0x3600b, // ondragenter
375 0x2e: 0x50902, // dt
376 0x2f: 0x5a708, // onsubmit
377 0x30: 0x27002, // hr
378 0x31: 0x32f0d, // oncontextmenu
379 0x33: 0x29c05, // image
380 0x34: 0x50d07, // onpause
381 0x35: 0x25906, // hgroup
382 0x36: 0x7704, // ping
383 0x37: 0x57808, // onselect
384 0x3a: 0x11303, // div
385 0x3b: 0x1fa0e, // onautocomplete
386 0x40: 0x2eb02, // mi
387 0x41: 0x31c08, // seamless
388 0x42: 0x2807, // charset
389 0x43: 0x8502, // id
390 0x44: 0x5200a, // onpopstate
391 0x45: 0x3ef03, // del
392 0x46: 0x2cb07, // marquee
393 0x47: 0x3309, // accesskey
394 0x49: 0x8d06, // footer
395 0x4a: 0x44e04, // list
396 0x4b: 0x2b005, // ismap
397 0x51: 0x33804, // menu
398 0x52: 0x2f04, // body
399 0x55: 0x9a08, // frameset
400 0x56: 0x54a07, // onreset
401 0x57: 0x12705, // blink
402 0x58: 0xa105, // title
403 0x59: 0x38807, // article
404 0x5b: 0x22e02, // th
405 0x5d: 0x13101, // q
406 0x5e: 0x3cf04, // open
407 0x5f: 0x2fa04, // area
408 0x61: 0x44206, // onload
409 0x62: 0xda04, // font
410 0x63: 0xd604, // base
411 0x64: 0x16207, // colspan
412 0x65: 0x53707, // keytype
413 0x66: 0x11e02, // dl
414 0x68: 0x1b008, // fieldset
415 0x6a: 0x2eb03, // min
416 0x6b: 0x11503, // var
417 0x6f: 0x2d506, // header
418 0x70: 0x13f02, // rt
419 0x71: 0x15008, // colgroup
420 0x72: 0x23502, // mn
421 0x74: 0x13a07, // onabort
422 0x75: 0x3906, // keygen
423 0x76: 0x4c209, // onoffline
424 0x77: 0x21f09, // challenge
425 0x78: 0x2b203, // map
426 0x7a: 0x2e902, // h4
427 0x7b: 0x3b607, // onerror
428 0x7c: 0x2e109, // maxlength
429 0x7d: 0x2f505, // mtext
430 0x7e: 0xbb07, // sandbox
431 0x7f: 0x58b06, // onsort
432 0x80: 0x100a, // malignmark
433 0x81: 0x45d04, // meta
434 0x82: 0x7b05, // async
435 0x83: 0x2a702, // h3
436 0x84: 0x26702, // dd
437 0x85: 0x27004, // href
438 0x86: 0x6e0a, // mediagroup
439 0x87: 0x19406, // coords
440 0x88: 0x41107, // srclang
441 0x89: 0x34d0a, // ondblclick
442 0x8a: 0x4005, // value
443 0x8c: 0xe908, // oncancel
444 0x8e: 0x3230a, // spellcheck
445 0x8f: 0x9a05, // frame
446 0x91: 0x12403, // big
447 0x94: 0x1f606, // action
448 0x95: 0x6903, // dir
449 0x97: 0x2fb08, // readonly
450 0x99: 0x42d05, // table
451 0x9a: 0x61607, // summary
452 0x9b: 0x12103, // wbr
453 0x9c: 0x30a, // radiogroup
454 0x9d: 0x6c04, // name
455 0x9f: 0x62306, // system
456 0xa1: 0x15d05, // color
457 0xa2: 0x7f06, // canvas
458 0xa3: 0x25504, // html
459 0xa5: 0x56f09, // onseeking
460 0xac: 0x4f905, // shape
461 0xad: 0x25f03, // rel
462 0xae: 0x28510, // oncanplaythrough
463 0xaf: 0x3760a, // ondragover
464 0xb0: 0x62608, // template
465 0xb1: 0x1d80d, // foreignObject
466 0xb3: 0x9204, // rows
467 0xb6: 0x44e07, // listing
468 0xb7: 0x49c06, // output
469 0xb9: 0x3310b, // contextmenu
470 0xbb: 0x11f03, // low
471 0xbc: 0x1c602, // rp
472 0xbd: 0x5bb09, // onsuspend
473 0xbe: 0x13606, // button
474 0xbf: 0x4db04, // desc
475 0xc1: 0x4e207, // section
476 0xc2: 0x52a0a, // onprogress
477 0xc3: 0x59e09, // onstorage
478 0xc4: 0x2d204, // math
479 0xc5: 0x4503, // alt
480 0xc7: 0x8a02, // ul
481 0xc8: 0x5107, // pattern
482 0xc9: 0x4b60c, // onmousewheel
483 0xca: 0x35709, // ondragend
484 0xcb: 0xaf04, // ruby
485 0xcc: 0xc01, // p
486 0xcd: 0x31707, // onclose
487 0xce: 0x24205, // meter
488 0xcf: 0x11807, // bgsound
489 0xd2: 0x25106, // height
490 0xd4: 0x101, // b
491 0xd5: 0x2c308, // itemtype
492 0xd8: 0x1bb07, // caption
493 0xd9: 0x10c08, // disabled
494 0xdb: 0x33808, // menuitem
495 0xdc: 0x62003, // svg
496 0xdd: 0x18f05, // small
497 0xde: 0x44a04, // data
498 0xe0: 0x4cb08, // ononline
499 0xe1: 0x2a206, // mglyph
500 0xe3: 0x6505, // embed
501 0xe4: 0x10502, // tr
502 0xe5: 0x46b0b, // onloadstart
503 0xe7: 0x3c306, // srcdoc
504 0xeb: 0x5c408, // ontoggle
505 0xed: 0xe703, // bdo
506 0xee: 0x4702, // td
507 0xef: 0x8305, // aside
508 0xf0: 0x29402, // h2
509 0xf1: 0x52c08, // progress
510 0xf2: 0x12c0a, // blockquote
511 0xf4: 0xf005, // label
512 0xf5: 0x601, // i
513 0xf7: 0x9207, // rowspan
514 0xfb: 0x51709, // onplaying
515 0xfd: 0x2a103, // img
516 0xfe: 0xf608, // optgroup
517 0xff: 0x42307, // content
518 0x101: 0x53e0c, // onratechange
519 0x103: 0x3da0c, // onhashchange
520 0x104: 0x4807, // details
521 0x106: 0x40008, // download
522 0x109: 0x14009, // translate
523 0x10b: 0x4230f, // contenteditable
524 0x10d: 0x36b0b, // ondragleave
525 0x10e: 0x2106, // accept
526 0x10f: 0x57a08, // selected
527 0x112: 0x1f20a, // formaction
528 0x113: 0x5b506, // center
529 0x115: 0x45510, // onloadedmetadata
530 0x116: 0x12804, // link
531 0x117: 0xdd04, // time
532 0x118: 0x19f0b, // crossorigin
533 0x119: 0x3bd07, // onfocus
534 0x11a: 0x58704, // wrap
535 0x11b: 0x42204, // icon
536 0x11d: 0x28105, // video
537 0x11e: 0x4de05, // class
538 0x121: 0x5d40e, // onvolumechange
539 0x122: 0xaa06, // onblur
540 0x123: 0x2b909, // itemscope
541 0x124: 0x61105, // style
542 0x127: 0x41e06, // public
543 0x129: 0x2320e, // formnovalidate
544 0x12a: 0x58206, // onshow
545 0x12c: 0x51706, // onplay
546 0x12d: 0x3c804, // cite
547 0x12e: 0x2bc02, // ms
548 0x12f: 0xdb0c, // ontimeupdate
549 0x130: 0x10904, // kind
550 0x131: 0x2470a, // formtarget
551 0x135: 0x3af07, // onended
552 0x136: 0x26506, // hidden
553 0x137: 0x2c01, // s
554 0x139: 0x2280a, // formmethod
555 0x13a: 0x3e805, // input
556 0x13c: 0x50b02, // h6
557 0x13d: 0xc902, // ol
558 0x13e: 0x3420b, // oncuechange
559 0x13f: 0x1e50d, // foreignobject
560 0x143: 0x4e70e, // onbeforeunload
561 0x144: 0x2bd05, // scope
562 0x145: 0x39609, // onemptied
563 0x146: 0x14b05, // defer
564 0x147: 0xc103, // xmp
565 0x148: 0x39f10, // ondurationchange
566 0x149: 0x1903, // kbd
567 0x14c: 0x47609, // onmessage
568 0x14d: 0x60006, // option
569 0x14e: 0x2eb09, // minlength
570 0x14f: 0x32807, // checked
571 0x150: 0xce08, // autoplay
572 0x152: 0x202, // br
573 0x153: 0x2360a, // novalidate
574 0x156: 0x6307, // noembed
575 0x159: 0x31007, // onclick
576 0x15a: 0x47f0b, // onmousedown
577 0x15b: 0x3a708, // onchange
578 0x15e: 0x3f209, // oninvalid
579 0x15f: 0x2bd06, // scoped
580 0x160: 0x18808, // controls
581 0x161: 0x30b05, // muted
582 0x162: 0x58d08, // sortable
583 0x163: 0x51106, // usemap
584 0x164: 0x1b80a, // figcaption
585 0x165: 0x35706, // ondrag
586 0x166: 0x26b04, // high
587 0x168: 0x3c303, // src
588 0x169: 0x15706, // poster
589 0x16b: 0x1670e, // annotation-xml
590 0x16c: 0x5f704, // step
591 0x16d: 0x4, // abbr
592 0x16e: 0x1b06, // dialog
593 0x170: 0x1202, // li
594 0x172: 0x3ed02, // mo
595 0x175: 0x1d803, // for
596 0x176: 0x1a803, // ins
597 0x178: 0x55504, // size
598 0x179: 0x43210, // onlanguagechange
599 0x17a: 0x8607, // default
600 0x17b: 0x1a03, // bdi
601 0x17c: 0x4d30a, // onpagehide
602 0x17d: 0x6907, // dirname
603 0x17e: 0x21404, // type
604 0x17f: 0x1f204, // form
605 0x181: 0x28509, // oncanplay
606 0x182: 0x6103, // dfn
607 0x183: 0x46308, // tabindex
608 0x186: 0x6502, // em
609 0x187: 0x27404, // lang
610 0x189: 0x39108, // dropzone
611 0x18a: 0x4080a, // onkeypress
612 0x18b: 0x23c08, // datetime
613 0x18c: 0x16204, // cols
614 0x18d: 0x1, // a
615 0x18e: 0x4420c, // onloadeddata
616 0x190: 0xa605, // audio
617 0x192: 0x2e05, // tbody
618 0x193: 0x22c06, // method
619 0x195: 0xf404, // loop
620 0x196: 0x29606, // iframe
621 0x198: 0x2d504, // head
622 0x19e: 0x5f108, // manifest
623 0x19f: 0xb309, // autofocus
624 0x1a0: 0x14904, // code
625 0x1a1: 0x55906, // strong
626 0x1a2: 0x30308, // multiple
627 0x1a3: 0xc05, // param
628 0x1a6: 0x21107, // enctype
629 0x1a7: 0x5b304, // face
630 0x1a8: 0xfd09, // plaintext
631 0x1a9: 0x26e02, // h1
632 0x1aa: 0x59509, // onstalled
633 0x1ad: 0x3d406, // script
634 0x1ae: 0x2db06, // spacer
635 0x1af: 0x55108, // onresize
636 0x1b0: 0x4a20b, // onmouseover
637 0x1b1: 0x5cc08, // onunload
638 0x1b2: 0x56708, // onseeked
639 0x1b4: 0x2140d, // typemustmatch
640 0x1b5: 0x1cc06, // figure
641 0x1b6: 0x4950a, // onmouseout
642 0x1b7: 0x25e03, // pre
643 0x1b8: 0x50705, // width
644 0x1b9: 0x19906, // sorted
645 0x1bb: 0x5704, // nobr
646 0x1be: 0x5302, // tt
647 0x1bf: 0x1105, // align
648 0x1c0: 0x3e607, // oninput
649 0x1c3: 0x41807, // onkeyup
650 0x1c6: 0x1c00c, // onafterprint
651 0x1c7: 0x210e, // accept-charset
652 0x1c8: 0x33c06, // itemid
653 0x1c9: 0x3e809, // inputmode
654 0x1cb: 0x53306, // strike
655 0x1cc: 0x5a903, // sub
656 0x1cd: 0x10505, // track
657 0x1ce: 0x38605, // start
658 0x1d0: 0xd608, // basefont
659 0x1d6: 0x1aa06, // source
660 0x1d7: 0x18206, // legend
661 0x1d8: 0x2d405, // thead
662 0x1da: 0x8c05, // tfoot
663 0x1dd: 0x1ec06, // object
664 0x1de: 0x6e05, // media
665 0x1df: 0x1670a, // annotation
666 0x1e0: 0x20d0b, // formenctype
667 0x1e2: 0x3d208, // noscript
668 0x1e4: 0x55505, // sizes
669 0x1e5: 0x1fc0c, // autocomplete
670 0x1e6: 0x9504, // span
671 0x1e7: 0x9808, // noframes
672 0x1e8: 0x24b06, // target
673 0x1e9: 0x38f06, // ondrop
674 0x1ea: 0x2b306, // applet
675 0x1ec: 0x5a08, // reversed
676 0x1f0: 0x2a907, // isindex
677 0x1f3: 0x27008, // hreflang
678 0x1f5: 0x2f302, // h5
679 0x1f6: 0x4f307, // address
680 0x1fa: 0x2e103, // max
681 0x1fb: 0xc30b, // placeholder
682 0x1fc: 0x2f608, // textarea
683 0x1fe: 0x4ad09, // onmouseup
684 0x1ff: 0x3800b, // ondragstart
685}
686
687const atomText = "abbradiogrouparamalignmarkbdialogaccept-charsetbodyaccesskey" +
688 "genavaluealtdetailsampatternobreversedfnoembedirnamediagroup" +
689 "ingasyncanvasidefaultfooterowspanoframesetitleaudionblurubya" +
690 "utofocusandboxmplaceholderautoplaybasefontimeupdatebdoncance" +
691 "labelooptgrouplaintextrackindisabledivarbgsoundlowbrbigblink" +
692 "blockquotebuttonabortranslatecodefercolgroupostercolorcolspa" +
693 "nnotation-xmlcommandraggablegendcontrolsmallcoordsortedcross" +
694 "originsourcefieldsetfigcaptionafterprintfigurequiredforeignO" +
695 "bjectforeignobjectformactionautocompleteerrorformenctypemust" +
696 "matchallengeformmethodformnovalidatetimeterformtargetheightm" +
697 "lhgroupreloadhiddenhigh1hreflanghttp-equivideoncanplaythroug" +
698 "h2iframeimageimglyph3isindexismappletitemscopeditemtypemarqu" +
699 "eematheaderspacermaxlength4minlength5mtextareadonlymultiplem" +
700 "utedonclickoncloseamlesspellcheckedoncontextmenuitemidoncuec" +
701 "hangeondblclickondragendondragenterondragleaveondragoverondr" +
702 "agstarticleondropzonemptiedondurationchangeonendedonerroronf" +
703 "ocusrcdocitempropenoscriptonhashchangeoninputmodeloninvalido" +
704 "nkeydownloadonkeypressrclangonkeyupublicontenteditableonlang" +
705 "uagechangeonloadeddatalistingonloadedmetadatabindexonloadsta" +
706 "rtonmessageonmousedownonmousemoveonmouseoutputonmouseoveronm" +
707 "ouseuponmousewheelonofflineononlineonpagehidesclassectionbef" +
708 "oreunloaddresshapeonpageshowidth6onpausemaponplayingonpopsta" +
709 "teonprogresstrikeytypeonratechangeonresetonresizestrongonscr" +
710 "ollonseekedonseekingonselectedonshowraponsortableonstalledon" +
711 "storageonsubmitemrefacenteronsuspendontoggleonunloadonvolume" +
712 "changeonwaitingoptimumanifestepromptoptionbeforeprintstylesu" +
713 "mmarysupsvgsystemplate"
diff --git a/vendor/golang.org/x/net/html/const.go b/vendor/golang.org/x/net/html/const.go
new file mode 100644
index 0000000..52f651f
--- /dev/null
+++ b/vendor/golang.org/x/net/html/const.go
@@ -0,0 +1,102 @@
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
5package html
6
7// Section 12.2.3.2 of the HTML5 specification says "The following elements
8// have varying levels of special parsing rules".
9// https://html.spec.whatwg.org/multipage/syntax.html#the-stack-of-open-elements
10var isSpecialElementMap = map[string]bool{
11 "address": true,
12 "applet": true,
13 "area": true,
14 "article": true,
15 "aside": true,
16 "base": true,
17 "basefont": true,
18 "bgsound": true,
19 "blockquote": true,
20 "body": true,
21 "br": true,
22 "button": true,
23 "caption": true,
24 "center": true,
25 "col": true,
26 "colgroup": true,
27 "dd": true,
28 "details": true,
29 "dir": true,
30 "div": true,
31 "dl": true,
32 "dt": true,
33 "embed": true,
34 "fieldset": true,
35 "figcaption": true,
36 "figure": true,
37 "footer": true,
38 "form": true,
39 "frame": true,
40 "frameset": true,
41 "h1": true,
42 "h2": true,
43 "h3": true,
44 "h4": true,
45 "h5": true,
46 "h6": true,
47 "head": true,
48 "header": true,
49 "hgroup": true,
50 "hr": true,
51 "html": true,
52 "iframe": true,
53 "img": true,
54 "input": true,
55 "isindex": true,
56 "li": true,
57 "link": true,
58 "listing": true,
59 "marquee": true,
60 "menu": true,
61 "meta": true,
62 "nav": true,
63 "noembed": true,
64 "noframes": true,
65 "noscript": true,
66 "object": true,
67 "ol": true,
68 "p": true,
69 "param": true,
70 "plaintext": true,
71 "pre": true,
72 "script": true,
73 "section": true,
74 "select": true,
75 "source": true,
76 "style": true,
77 "summary": true,
78 "table": true,
79 "tbody": true,
80 "td": true,
81 "template": true,
82 "textarea": true,
83 "tfoot": true,
84 "th": true,
85 "thead": true,
86 "title": true,
87 "tr": true,
88 "track": true,
89 "ul": true,
90 "wbr": true,
91 "xmp": true,
92}
93
94func isSpecialElement(element *Node) bool {
95 switch element.Namespace {
96 case "", "html":
97 return isSpecialElementMap[element.Data]
98 case "svg":
99 return element.Data == "foreignObject"
100 }
101 return false
102}
diff --git a/vendor/golang.org/x/net/html/doc.go b/vendor/golang.org/x/net/html/doc.go
new file mode 100644
index 0000000..94f4968
--- /dev/null
+++ b/vendor/golang.org/x/net/html/doc.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/*
6Package html implements an HTML5-compliant tokenizer and parser.
7
8Tokenization is done by creating a Tokenizer for an io.Reader r. It is the
9caller's responsibility to ensure that r provides UTF-8 encoded HTML.
10
11 z := html.NewTokenizer(r)
12
13Given a Tokenizer z, the HTML is tokenized by repeatedly calling z.Next(),
14which parses the next token and returns its type, or an error:
15
16 for {
17 tt := z.Next()
18 if tt == html.ErrorToken {
19 // ...
20 return ...
21 }
22 // Process the current token.
23 }
24
25There are two APIs for retrieving the current token. The high-level API is to
26call Token; the low-level API is to call Text or TagName / TagAttr. Both APIs
27allow optionally calling Raw after Next but before Token, Text, TagName, or
28TagAttr. In EBNF notation, the valid call sequence per token is:
29
30 Next {Raw} [ Token | Text | TagName {TagAttr} ]
31
32Token returns an independent data structure that completely describes a token.
33Entities (such as "&lt;") are unescaped, tag names and attribute keys are
34lower-cased, and attributes are collected into a []Attribute. For example:
35
36 for {
37 if z.Next() == html.ErrorToken {
38 // Returning io.EOF indicates success.
39 return z.Err()
40 }
41 emitToken(z.Token())
42 }
43
44The low-level API performs fewer allocations and copies, but the contents of
45the []byte values returned by Text, TagName and TagAttr may change on the next
46call to Next. For example, to extract an HTML page's anchor text:
47
48 depth := 0
49 for {
50 tt := z.Next()
51 switch tt {
52 case ErrorToken:
53 return z.Err()
54 case TextToken:
55 if depth > 0 {
56 // emitBytes should copy the []byte it receives,
57 // if it doesn't process it immediately.
58 emitBytes(z.Text())
59 }
60 case StartTagToken, EndTagToken:
61 tn, _ := z.TagName()
62 if len(tn) == 1 && tn[0] == 'a' {
63 if tt == StartTagToken {
64 depth++
65 } else {
66 depth--
67 }
68 }
69 }
70 }
71
72Parsing is done by calling Parse with an io.Reader, which returns the root of
73the parse tree (the document element) as a *Node. It is the caller's
74responsibility to ensure that the Reader provides UTF-8 encoded HTML. For
75example, to process each anchor node in depth-first order:
76
77 doc, err := html.Parse(r)
78 if err != nil {
79 // ...
80 }
81 var f func(*html.Node)
82 f = func(n *html.Node) {
83 if n.Type == html.ElementNode && n.Data == "a" {
84 // Do something with n...
85 }
86 for c := n.FirstChild; c != nil; c = c.NextSibling {
87 f(c)
88 }
89 }
90 f(doc)
91
92The relevant specifications include:
93https://html.spec.whatwg.org/multipage/syntax.html and
94https://html.spec.whatwg.org/multipage/syntax.html#tokenization
95*/
96package html // import "golang.org/x/net/html"
97
98// The tokenization algorithm implemented by this package is not a line-by-line
99// transliteration of the relatively verbose state-machine in the WHATWG
100// specification. A more direct approach is used instead, where the program
101// counter implies the state, such as whether it is tokenizing a tag or a text
102// node. Specification compliance is verified by checking expected and actual
103// outputs over a test suite rather than aiming for algorithmic fidelity.
104
105// TODO(nigeltao): Does a DOM API belong in this package or a separate one?
106// TODO(nigeltao): How does parsing interact with a JavaScript engine?
diff --git a/vendor/golang.org/x/net/html/doctype.go b/vendor/golang.org/x/net/html/doctype.go
new file mode 100644
index 0000000..c484e5a
--- /dev/null
+++ b/vendor/golang.org/x/net/html/doctype.go
@@ -0,0 +1,156 @@
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
5package html
6
7import (
8 "strings"
9)
10
11// parseDoctype parses the data from a DoctypeToken into a name,
12// public identifier, and system identifier. It returns a Node whose Type
13// is DoctypeNode, whose Data is the name, and which has attributes
14// named "system" and "public" for the two identifiers if they were present.
15// quirks is whether the document should be parsed in "quirks mode".
16func parseDoctype(s string) (n *Node, quirks bool) {
17 n = &Node{Type: DoctypeNode}
18
19 // Find the name.
20 space := strings.IndexAny(s, whitespace)
21 if space == -1 {
22 space = len(s)
23 }
24 n.Data = s[:space]
25 // The comparison to "html" is case-sensitive.
26 if n.Data != "html" {
27 quirks = true
28 }
29 n.Data = strings.ToLower(n.Data)
30 s = strings.TrimLeft(s[space:], whitespace)
31
32 if len(s) < 6 {
33 // It can't start with "PUBLIC" or "SYSTEM".
34 // Ignore the rest of the string.
35 return n, quirks || s != ""
36 }
37
38 key := strings.ToLower(s[:6])
39 s = s[6:]
40 for key == "public" || key == "system" {
41 s = strings.TrimLeft(s, whitespace)
42 if s == "" {
43 break
44 }
45 quote := s[0]
46 if quote != '"' && quote != '\'' {
47 break
48 }
49 s = s[1:]
50 q := strings.IndexRune(s, rune(quote))
51 var id string
52 if q == -1 {
53 id = s
54 s = ""
55 } else {
56 id = s[:q]
57 s = s[q+1:]
58 }
59 n.Attr = append(n.Attr, Attribute{Key: key, Val: id})
60 if key == "public" {
61 key = "system"
62 } else {
63 key = ""
64 }
65 }
66
67 if key != "" || s != "" {
68 quirks = true
69 } else if len(n.Attr) > 0 {
70 if n.Attr[0].Key == "public" {
71 public := strings.ToLower(n.Attr[0].Val)
72 switch public {
73 case "-//w3o//dtd w3 html strict 3.0//en//", "-/w3d/dtd html 4.0 transitional/en", "html":
74 quirks = true
75 default:
76 for _, q := range quirkyIDs {
77 if strings.HasPrefix(public, q) {
78 quirks = true
79 break
80 }
81 }
82 }
83 // The following two public IDs only cause quirks mode if there is no system ID.
84 if len(n.Attr) == 1 && (strings.HasPrefix(public, "-//w3c//dtd html 4.01 frameset//") ||
85 strings.HasPrefix(public, "-//w3c//dtd html 4.01 transitional//")) {
86 quirks = true
87 }
88 }
89 if lastAttr := n.Attr[len(n.Attr)-1]; lastAttr.Key == "system" &&
90 strings.ToLower(lastAttr.Val) == "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd" {
91 quirks = true
92 }
93 }
94
95 return n, quirks
96}
97
98// quirkyIDs is a list of public doctype identifiers that cause a document
99// to be interpreted in quirks mode. The identifiers should be in lower case.
100var quirkyIDs = []string{
101 "+//silmaril//dtd html pro v0r11 19970101//",
102 "-//advasoft ltd//dtd html 3.0 aswedit + extensions//",
103 "-//as//dtd html 3.0 aswedit + extensions//",
104 "-//ietf//dtd html 2.0 level 1//",
105 "-//ietf//dtd html 2.0 level 2//",
106 "-//ietf//dtd html 2.0 strict level 1//",
107 "-//ietf//dtd html 2.0 strict level 2//",
108 "-//ietf//dtd html 2.0 strict//",
109 "-//ietf//dtd html 2.0//",
110 "-//ietf//dtd html 2.1e//",
111 "-//ietf//dtd html 3.0//",
112 "-//ietf//dtd html 3.2 final//",
113 "-//ietf//dtd html 3.2//",
114 "-//ietf//dtd html 3//",
115 "-//ietf//dtd html level 0//",
116 "-//ietf//dtd html level 1//",
117 "-//ietf//dtd html level 2//",
118 "-//ietf//dtd html level 3//",
119 "-//ietf//dtd html strict level 0//",
120 "-//ietf//dtd html strict level 1//",
121 "-//ietf//dtd html strict level 2//",
122 "-//ietf//dtd html strict level 3//",
123 "-//ietf//dtd html strict//",
124 "-//ietf//dtd html//",
125 "-//metrius//dtd metrius presentational//",
126 "-//microsoft//dtd internet explorer 2.0 html strict//",
127 "-//microsoft//dtd internet explorer 2.0 html//",
128 "-//microsoft//dtd internet explorer 2.0 tables//",
129 "-//microsoft//dtd internet explorer 3.0 html strict//",
130 "-//microsoft//dtd internet explorer 3.0 html//",
131 "-//microsoft//dtd internet explorer 3.0 tables//",
132 "-//netscape comm. corp.//dtd html//",
133 "-//netscape comm. corp.//dtd strict html//",
134 "-//o'reilly and associates//dtd html 2.0//",
135 "-//o'reilly and associates//dtd html extended 1.0//",
136 "-//o'reilly and associates//dtd html extended relaxed 1.0//",
137 "-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//",
138 "-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//",
139 "-//spyglass//dtd html 2.0 extended//",
140 "-//sq//dtd html 2.0 hotmetal + extensions//",
141 "-//sun microsystems corp.//dtd hotjava html//",
142 "-//sun microsystems corp.//dtd hotjava strict html//",
143 "-//w3c//dtd html 3 1995-03-24//",
144 "-//w3c//dtd html 3.2 draft//",
145 "-//w3c//dtd html 3.2 final//",
146 "-//w3c//dtd html 3.2//",
147 "-//w3c//dtd html 3.2s draft//",
148 "-//w3c//dtd html 4.0 frameset//",
149 "-//w3c//dtd html 4.0 transitional//",
150 "-//w3c//dtd html experimental 19960712//",
151 "-//w3c//dtd html experimental 970421//",
152 "-//w3c//dtd w3 html//",
153 "-//w3o//dtd w3 html 3.0//",
154 "-//webtechs//dtd mozilla html 2.0//",
155 "-//webtechs//dtd mozilla html//",
156}
diff --git a/vendor/golang.org/x/net/html/entity.go b/vendor/golang.org/x/net/html/entity.go
new file mode 100644
index 0000000..a50c04c
--- /dev/null
+++ b/vendor/golang.org/x/net/html/entity.go
@@ -0,0 +1,2253 @@
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
5package html
6
7// All entities that do not end with ';' are 6 or fewer bytes long.
8const longestEntityWithoutSemicolon = 6
9
10// entity is a map from HTML entity names to their values. The semicolon matters:
11// https://html.spec.whatwg.org/multipage/syntax.html#named-character-references
12// lists both "amp" and "amp;" as two separate entries.
13//
14// Note that the HTML5 list is larger than the HTML4 list at
15// http://www.w3.org/TR/html4/sgml/entities.html
16var entity = map[string]rune{
17 "AElig;": '\U000000C6',
18 "AMP;": '\U00000026',
19 "Aacute;": '\U000000C1',
20 "Abreve;": '\U00000102',
21 "Acirc;": '\U000000C2',
22 "Acy;": '\U00000410',
23 "Afr;": '\U0001D504',
24 "Agrave;": '\U000000C0',
25 "Alpha;": '\U00000391',
26 "Amacr;": '\U00000100',
27 "And;": '\U00002A53',
28 "Aogon;": '\U00000104',
29 "Aopf;": '\U0001D538',
30 "ApplyFunction;": '\U00002061',
31 "Aring;": '\U000000C5',
32 "Ascr;": '\U0001D49C',
33 "Assign;": '\U00002254',
34 "Atilde;": '\U000000C3',
35 "Auml;": '\U000000C4',
36 "Backslash;": '\U00002216',
37 "Barv;": '\U00002AE7',
38 "Barwed;": '\U00002306',
39 "Bcy;": '\U00000411',
40 "Because;": '\U00002235',
41 "Bernoullis;": '\U0000212C',
42 "Beta;": '\U00000392',
43 "Bfr;": '\U0001D505',
44 "Bopf;": '\U0001D539',
45 "Breve;": '\U000002D8',
46 "Bscr;": '\U0000212C',
47 "Bumpeq;": '\U0000224E',
48 "CHcy;": '\U00000427',
49 "COPY;": '\U000000A9',
50 "Cacute;": '\U00000106',
51 "Cap;": '\U000022D2',
52 "CapitalDifferentialD;": '\U00002145',
53 "Cayleys;": '\U0000212D',
54 "Ccaron;": '\U0000010C',
55 "Ccedil;": '\U000000C7',
56 "Ccirc;": '\U00000108',
57 "Cconint;": '\U00002230',
58 "Cdot;": '\U0000010A',
59 "Cedilla;": '\U000000B8',
60 "CenterDot;": '\U000000B7',
61 "Cfr;": '\U0000212D',
62 "Chi;": '\U000003A7',
63 "CircleDot;": '\U00002299',
64 "CircleMinus;": '\U00002296',
65 "CirclePlus;": '\U00002295',
66 "CircleTimes;": '\U00002297',
67 "ClockwiseContourIntegral;": '\U00002232',
68 "CloseCurlyDoubleQuote;": '\U0000201D',
69 "CloseCurlyQuote;": '\U00002019',
70 "Colon;": '\U00002237',
71 "Colone;": '\U00002A74',
72 "Congruent;": '\U00002261',
73 "Conint;": '\U0000222F',
74 "ContourIntegral;": '\U0000222E',
75 "Copf;": '\U00002102',
76 "Coproduct;": '\U00002210',
77 "CounterClockwiseContourIntegral;": '\U00002233',
78 "Cross;": '\U00002A2F',
79 "Cscr;": '\U0001D49E',
80 "Cup;": '\U000022D3',
81 "CupCap;": '\U0000224D',
82 "DD;": '\U00002145',
83 "DDotrahd;": '\U00002911',
84 "DJcy;": '\U00000402',
85 "DScy;": '\U00000405',
86 "DZcy;": '\U0000040F',
87 "Dagger;": '\U00002021',
88 "Darr;": '\U000021A1',
89 "Dashv;": '\U00002AE4',
90 "Dcaron;": '\U0000010E',
91 "Dcy;": '\U00000414',
92 "Del;": '\U00002207',
93 "Delta;": '\U00000394',
94 "Dfr;": '\U0001D507',
95 "DiacriticalAcute;": '\U000000B4',
96 "DiacriticalDot;": '\U000002D9',
97 "DiacriticalDoubleAcute;": '\U000002DD',
98 "DiacriticalGrave;": '\U00000060',
99 "DiacriticalTilde;": '\U000002DC',
100 "Diamond;": '\U000022C4',
101 "DifferentialD;": '\U00002146',
102 "Dopf;": '\U0001D53B',
103 "Dot;": '\U000000A8',
104 "DotDot;": '\U000020DC',
105 "DotEqual;": '\U00002250',
106 "DoubleContourIntegral;": '\U0000222F',
107 "DoubleDot;": '\U000000A8',
108 "DoubleDownArrow;": '\U000021D3',
109 "DoubleLeftArrow;": '\U000021D0',
110 "DoubleLeftRightArrow;": '\U000021D4',
111 "DoubleLeftTee;": '\U00002AE4',
112 "DoubleLongLeftArrow;": '\U000027F8',
113 "DoubleLongLeftRightArrow;": '\U000027FA',
114 "DoubleLongRightArrow;": '\U000027F9',
115 "DoubleRightArrow;": '\U000021D2',
116 "DoubleRightTee;": '\U000022A8',
117 "DoubleUpArrow;": '\U000021D1',
118 "DoubleUpDownArrow;": '\U000021D5',
119 "DoubleVerticalBar;": '\U00002225',
120 "DownArrow;": '\U00002193',
121 "DownArrowBar;": '\U00002913',
122 "DownArrowUpArrow;": '\U000021F5',
123 "DownBreve;": '\U00000311',
124 "DownLeftRightVector;": '\U00002950',
125 "DownLeftTeeVector;": '\U0000295E',
126 "DownLeftVector;": '\U000021BD',
127 "DownLeftVectorBar;": '\U00002956',
128 "DownRightTeeVector;": '\U0000295F',
129 "DownRightVector;": '\U000021C1',
130 "DownRightVectorBar;": '\U00002957',
131 "DownTee;": '\U000022A4',
132 "DownTeeArrow;": '\U000021A7',
133 "Downarrow;": '\U000021D3',
134 "Dscr;": '\U0001D49F',
135 "Dstrok;": '\U00000110',
136 "ENG;": '\U0000014A',
137 "ETH;": '\U000000D0',
138 "Eacute;": '\U000000C9',
139 "Ecaron;": '\U0000011A',
140 "Ecirc;": '\U000000CA',
141 "Ecy;": '\U0000042D',
142 "Edot;": '\U00000116',
143 "Efr;": '\U0001D508',
144 "Egrave;": '\U000000C8',
145 "Element;": '\U00002208',
146 "Emacr;": '\U00000112',
147 "EmptySmallSquare;": '\U000025FB',
148 "EmptyVerySmallSquare;": '\U000025AB',
149 "Eogon;": '\U00000118',
150 "Eopf;": '\U0001D53C',
151 "Epsilon;": '\U00000395',
152 "Equal;": '\U00002A75',
153 "EqualTilde;": '\U00002242',
154 "Equilibrium;": '\U000021CC',
155 "Escr;": '\U00002130',
156 "Esim;": '\U00002A73',
157 "Eta;": '\U00000397',
158 "Euml;": '\U000000CB',
159 "Exists;": '\U00002203',
160 "ExponentialE;": '\U00002147',
161 "Fcy;": '\U00000424',
162 "Ffr;": '\U0001D509',
163 "FilledSmallSquare;": '\U000025FC',
164 "FilledVerySmallSquare;": '\U000025AA',
165 "Fopf;": '\U0001D53D',
166 "ForAll;": '\U00002200',
167 "Fouriertrf;": '\U00002131',
168 "Fscr;": '\U00002131',
169 "GJcy;": '\U00000403',
170 "GT;": '\U0000003E',
171 "Gamma;": '\U00000393',
172 "Gammad;": '\U000003DC',
173 "Gbreve;": '\U0000011E',
174 "Gcedil;": '\U00000122',
175 "Gcirc;": '\U0000011C',
176 "Gcy;": '\U00000413',
177 "Gdot;": '\U00000120',
178 "Gfr;": '\U0001D50A',
179 "Gg;": '\U000022D9',
180 "Gopf;": '\U0001D53E',
181 "GreaterEqual;": '\U00002265',
182 "GreaterEqualLess;": '\U000022DB',
183 "GreaterFullEqual;": '\U00002267',
184 "GreaterGreater;": '\U00002AA2',
185 "GreaterLess;": '\U00002277',
186 "GreaterSlantEqual;": '\U00002A7E',
187 "GreaterTilde;": '\U00002273',
188 "Gscr;": '\U0001D4A2',
189 "Gt;": '\U0000226B',
190 "HARDcy;": '\U0000042A',
191 "Hacek;": '\U000002C7',
192 "Hat;": '\U0000005E',
193 "Hcirc;": '\U00000124',
194 "Hfr;": '\U0000210C',
195 "HilbertSpace;": '\U0000210B',
196 "Hopf;": '\U0000210D',
197 "HorizontalLine;": '\U00002500',
198 "Hscr;": '\U0000210B',
199 "Hstrok;": '\U00000126',
200 "HumpDownHump;": '\U0000224E',
201 "HumpEqual;": '\U0000224F',
202 "IEcy;": '\U00000415',
203 "IJlig;": '\U00000132',
204 "IOcy;": '\U00000401',
205 "Iacute;": '\U000000CD',
206 "Icirc;": '\U000000CE',
207 "Icy;": '\U00000418',
208 "Idot;": '\U00000130',
209 "Ifr;": '\U00002111',
210 "Igrave;": '\U000000CC',
211 "Im;": '\U00002111',
212 "Imacr;": '\U0000012A',
213 "ImaginaryI;": '\U00002148',
214 "Implies;": '\U000021D2',
215 "Int;": '\U0000222C',
216 "Integral;": '\U0000222B',
217 "Intersection;": '\U000022C2',
218 "InvisibleComma;": '\U00002063',
219 "InvisibleTimes;": '\U00002062',
220 "Iogon;": '\U0000012E',
221 "Iopf;": '\U0001D540',
222 "Iota;": '\U00000399',
223 "Iscr;": '\U00002110',
224 "Itilde;": '\U00000128',
225 "Iukcy;": '\U00000406',
226 "Iuml;": '\U000000CF',
227 "Jcirc;": '\U00000134',
228 "Jcy;": '\U00000419',
229 "Jfr;": '\U0001D50D',
230 "Jopf;": '\U0001D541',
231 "Jscr;": '\U0001D4A5',
232 "Jsercy;": '\U00000408',
233 "Jukcy;": '\U00000404',
234 "KHcy;": '\U00000425',
235 "KJcy;": '\U0000040C',
236 "Kappa;": '\U0000039A',
237 "Kcedil;": '\U00000136',
238 "Kcy;": '\U0000041A',
239 "Kfr;": '\U0001D50E',
240 "Kopf;": '\U0001D542',
241 "Kscr;": '\U0001D4A6',
242 "LJcy;": '\U00000409',
243 "LT;": '\U0000003C',
244 "Lacute;": '\U00000139',
245 "Lambda;": '\U0000039B',
246 "Lang;": '\U000027EA',
247 "Laplacetrf;": '\U00002112',
248 "Larr;": '\U0000219E',
249 "Lcaron;": '\U0000013D',
250 "Lcedil;": '\U0000013B',
251 "Lcy;": '\U0000041B',
252 "LeftAngleBracket;": '\U000027E8',
253 "LeftArrow;": '\U00002190',
254 "LeftArrowBar;": '\U000021E4',
255 "LeftArrowRightArrow;": '\U000021C6',
256 "LeftCeiling;": '\U00002308',
257 "LeftDoubleBracket;": '\U000027E6',
258 "LeftDownTeeVector;": '\U00002961',
259 "LeftDownVector;": '\U000021C3',
260 "LeftDownVectorBar;": '\U00002959',
261 "LeftFloor;": '\U0000230A',
262 "LeftRightArrow;": '\U00002194',
263 "LeftRightVector;": '\U0000294E',
264 "LeftTee;": '\U000022A3',
265 "LeftTeeArrow;": '\U000021A4',
266 "LeftTeeVector;": '\U0000295A',
267 "LeftTriangle;": '\U000022B2',
268 "LeftTriangleBar;": '\U000029CF',
269 "LeftTriangleEqual;": '\U000022B4',
270 "LeftUpDownVector;": '\U00002951',
271 "LeftUpTeeVector;": '\U00002960',
272 "LeftUpVector;": '\U000021BF',
273 "LeftUpVectorBar;": '\U00002958',
274 "LeftVector;": '\U000021BC',
275 "LeftVectorBar;": '\U00002952',
276 "Leftarrow;": '\U000021D0',
277 "Leftrightarrow;": '\U000021D4',
278 "LessEqualGreater;": '\U000022DA',
279 "LessFullEqual;": '\U00002266',
280 "LessGreater;": '\U00002276',
281 "LessLess;": '\U00002AA1',
282 "LessSlantEqual;": '\U00002A7D',
283 "LessTilde;": '\U00002272',
284 "Lfr;": '\U0001D50F',
285 "Ll;": '\U000022D8',
286 "Lleftarrow;": '\U000021DA',
287 "Lmidot;": '\U0000013F',
288 "LongLeftArrow;": '\U000027F5',
289 "LongLeftRightArrow;": '\U000027F7',
290 "LongRightArrow;": '\U000027F6',
291 "Longleftarrow;": '\U000027F8',
292 "Longleftrightarrow;": '\U000027FA',
293 "Longrightarrow;": '\U000027F9',
294 "Lopf;": '\U0001D543',
295 "LowerLeftArrow;": '\U00002199',
296 "LowerRightArrow;": '\U00002198',
297 "Lscr;": '\U00002112',
298 "Lsh;": '\U000021B0',
299 "Lstrok;": '\U00000141',
300 "Lt;": '\U0000226A',
301 "Map;": '\U00002905',
302 "Mcy;": '\U0000041C',
303 "MediumSpace;": '\U0000205F',
304 "Mellintrf;": '\U00002133',
305 "Mfr;": '\U0001D510',
306 "MinusPlus;": '\U00002213',
307 "Mopf;": '\U0001D544',
308 "Mscr;": '\U00002133',
309 "Mu;": '\U0000039C',
310 "NJcy;": '\U0000040A',
311 "Nacute;": '\U00000143',
312 "Ncaron;": '\U00000147',
313 "Ncedil;": '\U00000145',
314 "Ncy;": '\U0000041D',
315 "NegativeMediumSpace;": '\U0000200B',
316 "NegativeThickSpace;": '\U0000200B',
317 "NegativeThinSpace;": '\U0000200B',
318 "NegativeVeryThinSpace;": '\U0000200B',
319 "NestedGreaterGreater;": '\U0000226B',
320 "NestedLessLess;": '\U0000226A',
321 "NewLine;": '\U0000000A',
322 "Nfr;": '\U0001D511',
323 "NoBreak;": '\U00002060',
324 "NonBreakingSpace;": '\U000000A0',
325 "Nopf;": '\U00002115',
326 "Not;": '\U00002AEC',
327 "NotCongruent;": '\U00002262',
328 "NotCupCap;": '\U0000226D',
329 "NotDoubleVerticalBar;": '\U00002226',
330 "NotElement;": '\U00002209',
331 "NotEqual;": '\U00002260',
332 "NotExists;": '\U00002204',
333 "NotGreater;": '\U0000226F',
334 "NotGreaterEqual;": '\U00002271',
335 "NotGreaterLess;": '\U00002279',
336 "NotGreaterTilde;": '\U00002275',
337 "NotLeftTriangle;": '\U000022EA',
338 "NotLeftTriangleEqual;": '\U000022EC',
339 "NotLess;": '\U0000226E',
340 "NotLessEqual;": '\U00002270',
341 "NotLessGreater;": '\U00002278',
342 "NotLessTilde;": '\U00002274',
343 "NotPrecedes;": '\U00002280',
344 "NotPrecedesSlantEqual;": '\U000022E0',
345 "NotReverseElement;": '\U0000220C',
346 "NotRightTriangle;": '\U000022EB',
347 "NotRightTriangleEqual;": '\U000022ED',
348 "NotSquareSubsetEqual;": '\U000022E2',
349 "NotSquareSupersetEqual;": '\U000022E3',
350 "NotSubsetEqual;": '\U00002288',
351 "NotSucceeds;": '\U00002281',
352 "NotSucceedsSlantEqual;": '\U000022E1',
353 "NotSupersetEqual;": '\U00002289',
354 "NotTilde;": '\U00002241',
355 "NotTildeEqual;": '\U00002244',
356 "NotTildeFullEqual;": '\U00002247',
357 "NotTildeTilde;": '\U00002249',
358 "NotVerticalBar;": '\U00002224',
359 "Nscr;": '\U0001D4A9',
360 "Ntilde;": '\U000000D1',
361 "Nu;": '\U0000039D',
362 "OElig;": '\U00000152',
363 "Oacute;": '\U000000D3',
364 "Ocirc;": '\U000000D4',
365 "Ocy;": '\U0000041E',
366 "Odblac;": '\U00000150',
367 "Ofr;": '\U0001D512',
368 "Ograve;": '\U000000D2',
369 "Omacr;": '\U0000014C',
370 "Omega;": '\U000003A9',
371 "Omicron;": '\U0000039F',
372 "Oopf;": '\U0001D546',
373 "OpenCurlyDoubleQuote;": '\U0000201C',
374 "OpenCurlyQuote;": '\U00002018',
375 "Or;": '\U00002A54',
376 "Oscr;": '\U0001D4AA',
377 "Oslash;": '\U000000D8',
378 "Otilde;": '\U000000D5',
379 "Otimes;": '\U00002A37',
380 "Ouml;": '\U000000D6',
381 "OverBar;": '\U0000203E',
382 "OverBrace;": '\U000023DE',
383 "OverBracket;": '\U000023B4',
384 "OverParenthesis;": '\U000023DC',
385 "PartialD;": '\U00002202',
386 "Pcy;": '\U0000041F',
387 "Pfr;": '\U0001D513',
388 "Phi;": '\U000003A6',
389 "Pi;": '\U000003A0',
390 "PlusMinus;": '\U000000B1',
391 "Poincareplane;": '\U0000210C',
392 "Popf;": '\U00002119',
393 "Pr;": '\U00002ABB',
394 "Precedes;": '\U0000227A',
395 "PrecedesEqual;": '\U00002AAF',
396 "PrecedesSlantEqual;": '\U0000227C',
397 "PrecedesTilde;": '\U0000227E',
398 "Prime;": '\U00002033',
399 "Product;": '\U0000220F',
400 "Proportion;": '\U00002237',
401 "Proportional;": '\U0000221D',
402 "Pscr;": '\U0001D4AB',
403 "Psi;": '\U000003A8',
404 "QUOT;": '\U00000022',
405 "Qfr;": '\U0001D514',
406 "Qopf;": '\U0000211A',
407 "Qscr;": '\U0001D4AC',
408 "RBarr;": '\U00002910',
409 "REG;": '\U000000AE',
410 "Racute;": '\U00000154',
411 "Rang;": '\U000027EB',
412 "Rarr;": '\U000021A0',
413 "Rarrtl;": '\U00002916',
414 "Rcaron;": '\U00000158',
415 "Rcedil;": '\U00000156',
416 "Rcy;": '\U00000420',
417 "Re;": '\U0000211C',
418 "ReverseElement;": '\U0000220B',
419 "ReverseEquilibrium;": '\U000021CB',
420 "ReverseUpEquilibrium;": '\U0000296F',
421 "Rfr;": '\U0000211C',
422 "Rho;": '\U000003A1',
423 "RightAngleBracket;": '\U000027E9',
424 "RightArrow;": '\U00002192',
425 "RightArrowBar;": '\U000021E5',
426 "RightArrowLeftArrow;": '\U000021C4',
427 "RightCeiling;": '\U00002309',
428 "RightDoubleBracket;": '\U000027E7',
429 "RightDownTeeVector;": '\U0000295D',
430 "RightDownVector;": '\U000021C2',
431 "RightDownVectorBar;": '\U00002955',
432 "RightFloor;": '\U0000230B',
433 "RightTee;": '\U000022A2',
434 "RightTeeArrow;": '\U000021A6',
435 "RightTeeVector;": '\U0000295B',
436 "RightTriangle;": '\U000022B3',
437 "RightTriangleBar;": '\U000029D0',
438 "RightTriangleEqual;": '\U000022B5',
439 "RightUpDownVector;": '\U0000294F',
440 "RightUpTeeVector;": '\U0000295C',
441 "RightUpVector;": '\U000021BE',
442 "RightUpVectorBar;": '\U00002954',
443 "RightVector;": '\U000021C0',
444 "RightVectorBar;": '\U00002953',
445 "Rightarrow;": '\U000021D2',
446 "Ropf;": '\U0000211D',
447 "RoundImplies;": '\U00002970',
448 "Rrightarrow;": '\U000021DB',
449 "Rscr;": '\U0000211B',
450 "Rsh;": '\U000021B1',
451 "RuleDelayed;": '\U000029F4',
452 "SHCHcy;": '\U00000429',
453 "SHcy;": '\U00000428',
454 "SOFTcy;": '\U0000042C',
455 "Sacute;": '\U0000015A',
456 "Sc;": '\U00002ABC',
457 "Scaron;": '\U00000160',
458 "Scedil;": '\U0000015E',
459 "Scirc;": '\U0000015C',
460 "Scy;": '\U00000421',
461 "Sfr;": '\U0001D516',
462 "ShortDownArrow;": '\U00002193',
463 "ShortLeftArrow;": '\U00002190',
464 "ShortRightArrow;": '\U00002192',
465 "ShortUpArrow;": '\U00002191',
466 "Sigma;": '\U000003A3',
467 "SmallCircle;": '\U00002218',
468 "Sopf;": '\U0001D54A',
469 "Sqrt;": '\U0000221A',
470 "Square;": '\U000025A1',
471 "SquareIntersection;": '\U00002293',
472 "SquareSubset;": '\U0000228F',
473 "SquareSubsetEqual;": '\U00002291',
474 "SquareSuperset;": '\U00002290',
475 "SquareSupersetEqual;": '\U00002292',
476 "SquareUnion;": '\U00002294',
477 "Sscr;": '\U0001D4AE',
478 "Star;": '\U000022C6',
479 "Sub;": '\U000022D0',
480 "Subset;": '\U000022D0',
481 "SubsetEqual;": '\U00002286',
482 "Succeeds;": '\U0000227B',
483 "SucceedsEqual;": '\U00002AB0',
484 "SucceedsSlantEqual;": '\U0000227D',
485 "SucceedsTilde;": '\U0000227F',
486 "SuchThat;": '\U0000220B',
487 "Sum;": '\U00002211',
488 "Sup;": '\U000022D1',
489 "Superset;": '\U00002283',
490 "SupersetEqual;": '\U00002287',
491 "Supset;": '\U000022D1',
492 "THORN;": '\U000000DE',
493 "TRADE;": '\U00002122',
494 "TSHcy;": '\U0000040B',
495 "TScy;": '\U00000426',
496 "Tab;": '\U00000009',
497 "Tau;": '\U000003A4',
498 "Tcaron;": '\U00000164',
499 "Tcedil;": '\U00000162',
500 "Tcy;": '\U00000422',
501 "Tfr;": '\U0001D517',
502 "Therefore;": '\U00002234',
503 "Theta;": '\U00000398',
504 "ThinSpace;": '\U00002009',
505 "Tilde;": '\U0000223C',
506 "TildeEqual;": '\U00002243',
507 "TildeFullEqual;": '\U00002245',
508 "TildeTilde;": '\U00002248',
509 "Topf;": '\U0001D54B',
510 "TripleDot;": '\U000020DB',
511 "Tscr;": '\U0001D4AF',
512 "Tstrok;": '\U00000166',
513 "Uacute;": '\U000000DA',
514 "Uarr;": '\U0000219F',
515 "Uarrocir;": '\U00002949',
516 "Ubrcy;": '\U0000040E',
517 "Ubreve;": '\U0000016C',
518 "Ucirc;": '\U000000DB',
519 "Ucy;": '\U00000423',
520 "Udblac;": '\U00000170',
521 "Ufr;": '\U0001D518',
522 "Ugrave;": '\U000000D9',
523 "Umacr;": '\U0000016A',
524 "UnderBar;": '\U0000005F',
525 "UnderBrace;": '\U000023DF',
526 "UnderBracket;": '\U000023B5',
527 "UnderParenthesis;": '\U000023DD',
528 "Union;": '\U000022C3',
529 "UnionPlus;": '\U0000228E',
530 "Uogon;": '\U00000172',
531 "Uopf;": '\U0001D54C',
532 "UpArrow;": '\U00002191',
533 "UpArrowBar;": '\U00002912',
534 "UpArrowDownArrow;": '\U000021C5',
535 "UpDownArrow;": '\U00002195',
536 "UpEquilibrium;": '\U0000296E',
537 "UpTee;": '\U000022A5',
538 "UpTeeArrow;": '\U000021A5',
539 "Uparrow;": '\U000021D1',
540 "Updownarrow;": '\U000021D5',
541 "UpperLeftArrow;": '\U00002196',
542 "UpperRightArrow;": '\U00002197',
543 "Upsi;": '\U000003D2',
544 "Upsilon;": '\U000003A5',
545 "Uring;": '\U0000016E',
546 "Uscr;": '\U0001D4B0',
547 "Utilde;": '\U00000168',
548 "Uuml;": '\U000000DC',
549 "VDash;": '\U000022AB',
550 "Vbar;": '\U00002AEB',
551 "Vcy;": '\U00000412',
552 "Vdash;": '\U000022A9',
553 "Vdashl;": '\U00002AE6',
554 "Vee;": '\U000022C1',
555 "Verbar;": '\U00002016',
556 "Vert;": '\U00002016',
557 "VerticalBar;": '\U00002223',
558 "VerticalLine;": '\U0000007C',
559 "VerticalSeparator;": '\U00002758',
560 "VerticalTilde;": '\U00002240',
561 "VeryThinSpace;": '\U0000200A',
562 "Vfr;": '\U0001D519',
563 "Vopf;": '\U0001D54D',
564 "Vscr;": '\U0001D4B1',
565 "Vvdash;": '\U000022AA',
566 "Wcirc;": '\U00000174',
567 "Wedge;": '\U000022C0',
568 "Wfr;": '\U0001D51A',
569 "Wopf;": '\U0001D54E',
570 "Wscr;": '\U0001D4B2',
571 "Xfr;": '\U0001D51B',
572 "Xi;": '\U0000039E',
573 "Xopf;": '\U0001D54F',
574 "Xscr;": '\U0001D4B3',
575 "YAcy;": '\U0000042F',
576 "YIcy;": '\U00000407',
577 "YUcy;": '\U0000042E',
578 "Yacute;": '\U000000DD',
579 "Ycirc;": '\U00000176',
580 "Ycy;": '\U0000042B',
581 "Yfr;": '\U0001D51C',
582 "Yopf;": '\U0001D550',
583 "Yscr;": '\U0001D4B4',
584 "Yuml;": '\U00000178',
585 "ZHcy;": '\U00000416',
586 "Zacute;": '\U00000179',
587 "Zcaron;": '\U0000017D',
588 "Zcy;": '\U00000417',
589 "Zdot;": '\U0000017B',
590 "ZeroWidthSpace;": '\U0000200B',
591 "Zeta;": '\U00000396',
592 "Zfr;": '\U00002128',
593 "Zopf;": '\U00002124',
594 "Zscr;": '\U0001D4B5',
595 "aacute;": '\U000000E1',
596 "abreve;": '\U00000103',
597 "ac;": '\U0000223E',
598 "acd;": '\U0000223F',
599 "acirc;": '\U000000E2',
600 "acute;": '\U000000B4',
601 "acy;": '\U00000430',
602 "aelig;": '\U000000E6',
603 "af;": '\U00002061',
604 "afr;": '\U0001D51E',
605 "agrave;": '\U000000E0',
606 "alefsym;": '\U00002135',
607 "aleph;": '\U00002135',
608 "alpha;": '\U000003B1',
609 "amacr;": '\U00000101',
610 "amalg;": '\U00002A3F',
611 "amp;": '\U00000026',
612 "and;": '\U00002227',
613 "andand;": '\U00002A55',
614 "andd;": '\U00002A5C',
615 "andslope;": '\U00002A58',
616 "andv;": '\U00002A5A',
617 "ang;": '\U00002220',
618 "ange;": '\U000029A4',
619 "angle;": '\U00002220',
620 "angmsd;": '\U00002221',
621 "angmsdaa;": '\U000029A8',
622 "angmsdab;": '\U000029A9',
623 "angmsdac;": '\U000029AA',
624 "angmsdad;": '\U000029AB',
625 "angmsdae;": '\U000029AC',
626 "angmsdaf;": '\U000029AD',
627 "angmsdag;": '\U000029AE',
628 "angmsdah;": '\U000029AF',
629 "angrt;": '\U0000221F',
630 "angrtvb;": '\U000022BE',
631 "angrtvbd;": '\U0000299D',
632 "angsph;": '\U00002222',
633 "angst;": '\U000000C5',
634 "angzarr;": '\U0000237C',
635 "aogon;": '\U00000105',
636 "aopf;": '\U0001D552',
637 "ap;": '\U00002248',
638 "apE;": '\U00002A70',
639 "apacir;": '\U00002A6F',
640 "ape;": '\U0000224A',
641 "apid;": '\U0000224B',
642 "apos;": '\U00000027',
643 "approx;": '\U00002248',
644 "approxeq;": '\U0000224A',
645 "aring;": '\U000000E5',
646 "ascr;": '\U0001D4B6',
647 "ast;": '\U0000002A',
648 "asymp;": '\U00002248',
649 "asympeq;": '\U0000224D',
650 "atilde;": '\U000000E3',
651 "auml;": '\U000000E4',
652 "awconint;": '\U00002233',
653 "awint;": '\U00002A11',
654 "bNot;": '\U00002AED',
655 "backcong;": '\U0000224C',
656 "backepsilon;": '\U000003F6',
657 "backprime;": '\U00002035',
658 "backsim;": '\U0000223D',
659 "backsimeq;": '\U000022CD',
660 "barvee;": '\U000022BD',
661 "barwed;": '\U00002305',
662 "barwedge;": '\U00002305',
663 "bbrk;": '\U000023B5',
664 "bbrktbrk;": '\U000023B6',
665 "bcong;": '\U0000224C',
666 "bcy;": '\U00000431',
667 "bdquo;": '\U0000201E',
668 "becaus;": '\U00002235',
669 "because;": '\U00002235',
670 "bemptyv;": '\U000029B0',
671 "bepsi;": '\U000003F6',
672 "bernou;": '\U0000212C',
673 "beta;": '\U000003B2',
674 "beth;": '\U00002136',
675 "between;": '\U0000226C',
676 "bfr;": '\U0001D51F',
677 "bigcap;": '\U000022C2',
678 "bigcirc;": '\U000025EF',
679 "bigcup;": '\U000022C3',
680 "bigodot;": '\U00002A00',
681 "bigoplus;": '\U00002A01',
682 "bigotimes;": '\U00002A02',
683 "bigsqcup;": '\U00002A06',
684 "bigstar;": '\U00002605',
685 "bigtriangledown;": '\U000025BD',
686 "bigtriangleup;": '\U000025B3',
687 "biguplus;": '\U00002A04',
688 "bigvee;": '\U000022C1',
689 "bigwedge;": '\U000022C0',
690 "bkarow;": '\U0000290D',
691 "blacklozenge;": '\U000029EB',
692 "blacksquare;": '\U000025AA',
693 "blacktriangle;": '\U000025B4',
694 "blacktriangledown;": '\U000025BE',
695 "blacktriangleleft;": '\U000025C2',
696 "blacktriangleright;": '\U000025B8',
697 "blank;": '\U00002423',
698 "blk12;": '\U00002592',
699 "blk14;": '\U00002591',
700 "blk34;": '\U00002593',
701 "block;": '\U00002588',
702 "bnot;": '\U00002310',
703 "bopf;": '\U0001D553',
704 "bot;": '\U000022A5',
705 "bottom;": '\U000022A5',
706 "bowtie;": '\U000022C8',
707 "boxDL;": '\U00002557',
708 "boxDR;": '\U00002554',
709 "boxDl;": '\U00002556',
710 "boxDr;": '\U00002553',
711 "boxH;": '\U00002550',
712 "boxHD;": '\U00002566',
713 "boxHU;": '\U00002569',
714 "boxHd;": '\U00002564',
715 "boxHu;": '\U00002567',
716 "boxUL;": '\U0000255D',
717 "boxUR;": '\U0000255A',
718 "boxUl;": '\U0000255C',
719 "boxUr;": '\U00002559',
720 "boxV;": '\U00002551',
721 "boxVH;": '\U0000256C',
722 "boxVL;": '\U00002563',
723 "boxVR;": '\U00002560',
724 "boxVh;": '\U0000256B',
725 "boxVl;": '\U00002562',
726 "boxVr;": '\U0000255F',
727 "boxbox;": '\U000029C9',
728 "boxdL;": '\U00002555',
729 "boxdR;": '\U00002552',
730 "boxdl;": '\U00002510',
731 "boxdr;": '\U0000250C',
732 "boxh;": '\U00002500',
733 "boxhD;": '\U00002565',
734 "boxhU;": '\U00002568',
735 "boxhd;": '\U0000252C',
736 "boxhu;": '\U00002534',
737 "boxminus;": '\U0000229F',
738 "boxplus;": '\U0000229E',
739 "boxtimes;": '\U000022A0',
740 "boxuL;": '\U0000255B',
741 "boxuR;": '\U00002558',
742 "boxul;": '\U00002518',
743 "boxur;": '\U00002514',
744 "boxv;": '\U00002502',
745 "boxvH;": '\U0000256A',
746 "boxvL;": '\U00002561',
747 "boxvR;": '\U0000255E',
748 "boxvh;": '\U0000253C',
749 "boxvl;": '\U00002524',
750 "boxvr;": '\U0000251C',
751 "bprime;": '\U00002035',
752 "breve;": '\U000002D8',
753 "brvbar;": '\U000000A6',
754 "bscr;": '\U0001D4B7',
755 "bsemi;": '\U0000204F',
756 "bsim;": '\U0000223D',
757 "bsime;": '\U000022CD',
758 "bsol;": '\U0000005C',
759 "bsolb;": '\U000029C5',
760 "bsolhsub;": '\U000027C8',
761 "bull;": '\U00002022',
762 "bullet;": '\U00002022',
763 "bump;": '\U0000224E',
764 "bumpE;": '\U00002AAE',
765 "bumpe;": '\U0000224F',
766 "bumpeq;": '\U0000224F',
767 "cacute;": '\U00000107',
768 "cap;": '\U00002229',
769 "capand;": '\U00002A44',
770 "capbrcup;": '\U00002A49',
771 "capcap;": '\U00002A4B',
772 "capcup;": '\U00002A47',
773 "capdot;": '\U00002A40',
774 "caret;": '\U00002041',
775 "caron;": '\U000002C7',
776 "ccaps;": '\U00002A4D',
777 "ccaron;": '\U0000010D',
778 "ccedil;": '\U000000E7',
779 "ccirc;": '\U00000109',
780 "ccups;": '\U00002A4C',
781 "ccupssm;": '\U00002A50',
782 "cdot;": '\U0000010B',
783 "cedil;": '\U000000B8',
784 "cemptyv;": '\U000029B2',
785 "cent;": '\U000000A2',
786 "centerdot;": '\U000000B7',
787 "cfr;": '\U0001D520',
788 "chcy;": '\U00000447',
789 "check;": '\U00002713',
790 "checkmark;": '\U00002713',
791 "chi;": '\U000003C7',
792 "cir;": '\U000025CB',
793 "cirE;": '\U000029C3',
794 "circ;": '\U000002C6',
795 "circeq;": '\U00002257',
796 "circlearrowleft;": '\U000021BA',
797 "circlearrowright;": '\U000021BB',
798 "circledR;": '\U000000AE',
799 "circledS;": '\U000024C8',
800 "circledast;": '\U0000229B',
801 "circledcirc;": '\U0000229A',
802 "circleddash;": '\U0000229D',
803 "cire;": '\U00002257',
804 "cirfnint;": '\U00002A10',
805 "cirmid;": '\U00002AEF',
806 "cirscir;": '\U000029C2',
807 "clubs;": '\U00002663',
808 "clubsuit;": '\U00002663',
809 "colon;": '\U0000003A',
810 "colone;": '\U00002254',
811 "coloneq;": '\U00002254',
812 "comma;": '\U0000002C',
813 "commat;": '\U00000040',
814 "comp;": '\U00002201',
815 "compfn;": '\U00002218',
816 "complement;": '\U00002201',
817 "complexes;": '\U00002102',
818 "cong;": '\U00002245',
819 "congdot;": '\U00002A6D',
820 "conint;": '\U0000222E',
821 "copf;": '\U0001D554',
822 "coprod;": '\U00002210',
823 "copy;": '\U000000A9',
824 "copysr;": '\U00002117',
825 "crarr;": '\U000021B5',
826 "cross;": '\U00002717',
827 "cscr;": '\U0001D4B8',
828 "csub;": '\U00002ACF',
829 "csube;": '\U00002AD1',
830 "csup;": '\U00002AD0',
831 "csupe;": '\U00002AD2',
832 "ctdot;": '\U000022EF',
833 "cudarrl;": '\U00002938',
834 "cudarrr;": '\U00002935',
835 "cuepr;": '\U000022DE',
836 "cuesc;": '\U000022DF',
837 "cularr;": '\U000021B6',
838 "cularrp;": '\U0000293D',
839 "cup;": '\U0000222A',
840 "cupbrcap;": '\U00002A48',
841 "cupcap;": '\U00002A46',
842 "cupcup;": '\U00002A4A',
843 "cupdot;": '\U0000228D',
844 "cupor;": '\U00002A45',
845 "curarr;": '\U000021B7',
846 "curarrm;": '\U0000293C',
847 "curlyeqprec;": '\U000022DE',
848 "curlyeqsucc;": '\U000022DF',
849 "curlyvee;": '\U000022CE',
850 "curlywedge;": '\U000022CF',
851 "curren;": '\U000000A4',
852 "curvearrowleft;": '\U000021B6',
853 "curvearrowright;": '\U000021B7',
854 "cuvee;": '\U000022CE',
855 "cuwed;": '\U000022CF',
856 "cwconint;": '\U00002232',
857 "cwint;": '\U00002231',
858 "cylcty;": '\U0000232D',
859 "dArr;": '\U000021D3',
860 "dHar;": '\U00002965',
861 "dagger;": '\U00002020',
862 "daleth;": '\U00002138',
863 "darr;": '\U00002193',
864 "dash;": '\U00002010',
865 "dashv;": '\U000022A3',
866 "dbkarow;": '\U0000290F',
867 "dblac;": '\U000002DD',
868 "dcaron;": '\U0000010F',
869 "dcy;": '\U00000434',
870 "dd;": '\U00002146',
871 "ddagger;": '\U00002021',
872 "ddarr;": '\U000021CA',
873 "ddotseq;": '\U00002A77',
874 "deg;": '\U000000B0',
875 "delta;": '\U000003B4',
876 "demptyv;": '\U000029B1',
877 "dfisht;": '\U0000297F',
878 "dfr;": '\U0001D521',
879 "dharl;": '\U000021C3',
880 "dharr;": '\U000021C2',
881 "diam;": '\U000022C4',
882 "diamond;": '\U000022C4',
883 "diamondsuit;": '\U00002666',
884 "diams;": '\U00002666',
885 "die;": '\U000000A8',
886 "digamma;": '\U000003DD',
887 "disin;": '\U000022F2',
888 "div;": '\U000000F7',
889 "divide;": '\U000000F7',
890 "divideontimes;": '\U000022C7',
891 "divonx;": '\U000022C7',
892 "djcy;": '\U00000452',
893 "dlcorn;": '\U0000231E',
894 "dlcrop;": '\U0000230D',
895 "dollar;": '\U00000024',
896 "dopf;": '\U0001D555',
897 "dot;": '\U000002D9',
898 "doteq;": '\U00002250',
899 "doteqdot;": '\U00002251',
900 "dotminus;": '\U00002238',
901 "dotplus;": '\U00002214',
902 "dotsquare;": '\U000022A1',
903 "doublebarwedge;": '\U00002306',
904 "downarrow;": '\U00002193',
905 "downdownarrows;": '\U000021CA',
906 "downharpoonleft;": '\U000021C3',
907 "downharpoonright;": '\U000021C2',
908 "drbkarow;": '\U00002910',
909 "drcorn;": '\U0000231F',
910 "drcrop;": '\U0000230C',
911 "dscr;": '\U0001D4B9',
912 "dscy;": '\U00000455',
913 "dsol;": '\U000029F6',
914 "dstrok;": '\U00000111',
915 "dtdot;": '\U000022F1',
916 "dtri;": '\U000025BF',
917 "dtrif;": '\U000025BE',
918 "duarr;": '\U000021F5',
919 "duhar;": '\U0000296F',
920 "dwangle;": '\U000029A6',
921 "dzcy;": '\U0000045F',
922 "dzigrarr;": '\U000027FF',
923 "eDDot;": '\U00002A77',
924 "eDot;": '\U00002251',
925 "eacute;": '\U000000E9',
926 "easter;": '\U00002A6E',
927 "ecaron;": '\U0000011B',
928 "ecir;": '\U00002256',
929 "ecirc;": '\U000000EA',
930 "ecolon;": '\U00002255',
931 "ecy;": '\U0000044D',
932 "edot;": '\U00000117',
933 "ee;": '\U00002147',
934 "efDot;": '\U00002252',
935 "efr;": '\U0001D522',
936 "eg;": '\U00002A9A',
937 "egrave;": '\U000000E8',
938 "egs;": '\U00002A96',
939 "egsdot;": '\U00002A98',
940 "el;": '\U00002A99',
941 "elinters;": '\U000023E7',
942 "ell;": '\U00002113',
943 "els;": '\U00002A95',
944 "elsdot;": '\U00002A97',
945 "emacr;": '\U00000113',
946 "empty;": '\U00002205',
947 "emptyset;": '\U00002205',
948 "emptyv;": '\U00002205',
949 "emsp;": '\U00002003',
950 "emsp13;": '\U00002004',
951 "emsp14;": '\U00002005',
952 "eng;": '\U0000014B',
953 "ensp;": '\U00002002',
954 "eogon;": '\U00000119',
955 "eopf;": '\U0001D556',
956 "epar;": '\U000022D5',
957 "eparsl;": '\U000029E3',
958 "eplus;": '\U00002A71',
959 "epsi;": '\U000003B5',
960 "epsilon;": '\U000003B5',
961 "epsiv;": '\U000003F5',
962 "eqcirc;": '\U00002256',
963 "eqcolon;": '\U00002255',
964 "eqsim;": '\U00002242',
965 "eqslantgtr;": '\U00002A96',
966 "eqslantless;": '\U00002A95',
967 "equals;": '\U0000003D',
968 "equest;": '\U0000225F',
969 "equiv;": '\U00002261',
970 "equivDD;": '\U00002A78',
971 "eqvparsl;": '\U000029E5',
972 "erDot;": '\U00002253',
973 "erarr;": '\U00002971',
974 "escr;": '\U0000212F',
975 "esdot;": '\U00002250',
976 "esim;": '\U00002242',
977 "eta;": '\U000003B7',
978 "eth;": '\U000000F0',
979 "euml;": '\U000000EB',
980 "euro;": '\U000020AC',
981 "excl;": '\U00000021',
982 "exist;": '\U00002203',
983 "expectation;": '\U00002130',
984 "exponentiale;": '\U00002147',
985 "fallingdotseq;": '\U00002252',
986 "fcy;": '\U00000444',
987 "female;": '\U00002640',
988 "ffilig;": '\U0000FB03',
989 "fflig;": '\U0000FB00',
990 "ffllig;": '\U0000FB04',
991 "ffr;": '\U0001D523',
992 "filig;": '\U0000FB01',
993 "flat;": '\U0000266D',
994 "fllig;": '\U0000FB02',
995 "fltns;": '\U000025B1',
996 "fnof;": '\U00000192',
997 "fopf;": '\U0001D557',
998 "forall;": '\U00002200',
999 "fork;": '\U000022D4',
1000 "forkv;": '\U00002AD9',
1001 "fpartint;": '\U00002A0D',
1002 "frac12;": '\U000000BD',
1003 "frac13;": '\U00002153',
1004 "frac14;": '\U000000BC',
1005 "frac15;": '\U00002155',
1006 "frac16;": '\U00002159',
1007 "frac18;": '\U0000215B',
1008 "frac23;": '\U00002154',
1009 "frac25;": '\U00002156',
1010 "frac34;": '\U000000BE',
1011 "frac35;": '\U00002157',
1012 "frac38;": '\U0000215C',
1013 "frac45;": '\U00002158',
1014 "frac56;": '\U0000215A',
1015 "frac58;": '\U0000215D',
1016 "frac78;": '\U0000215E',
1017 "frasl;": '\U00002044',
1018 "frown;": '\U00002322',
1019 "fscr;": '\U0001D4BB',
1020 "gE;": '\U00002267',
1021 "gEl;": '\U00002A8C',
1022 "gacute;": '\U000001F5',
1023 "gamma;": '\U000003B3',
1024 "gammad;": '\U000003DD',
1025 "gap;": '\U00002A86',
1026 "gbreve;": '\U0000011F',
1027 "gcirc;": '\U0000011D',
1028 "gcy;": '\U00000433',
1029 "gdot;": '\U00000121',
1030 "ge;": '\U00002265',
1031 "gel;": '\U000022DB',
1032 "geq;": '\U00002265',
1033 "geqq;": '\U00002267',
1034 "geqslant;": '\U00002A7E',
1035 "ges;": '\U00002A7E',
1036 "gescc;": '\U00002AA9',
1037 "gesdot;": '\U00002A80',
1038 "gesdoto;": '\U00002A82',
1039 "gesdotol;": '\U00002A84',
1040 "gesles;": '\U00002A94',
1041 "gfr;": '\U0001D524',
1042 "gg;": '\U0000226B',
1043 "ggg;": '\U000022D9',
1044 "gimel;": '\U00002137',
1045 "gjcy;": '\U00000453',
1046 "gl;": '\U00002277',
1047 "glE;": '\U00002A92',
1048 "gla;": '\U00002AA5',
1049 "glj;": '\U00002AA4',
1050 "gnE;": '\U00002269',
1051 "gnap;": '\U00002A8A',
1052 "gnapprox;": '\U00002A8A',
1053 "gne;": '\U00002A88',
1054 "gneq;": '\U00002A88',
1055 "gneqq;": '\U00002269',
1056 "gnsim;": '\U000022E7',
1057 "gopf;": '\U0001D558',
1058 "grave;": '\U00000060',
1059 "gscr;": '\U0000210A',
1060 "gsim;": '\U00002273',
1061 "gsime;": '\U00002A8E',
1062 "gsiml;": '\U00002A90',
1063 "gt;": '\U0000003E',
1064 "gtcc;": '\U00002AA7',
1065 "gtcir;": '\U00002A7A',
1066 "gtdot;": '\U000022D7',
1067 "gtlPar;": '\U00002995',
1068 "gtquest;": '\U00002A7C',
1069 "gtrapprox;": '\U00002A86',
1070 "gtrarr;": '\U00002978',
1071 "gtrdot;": '\U000022D7',
1072 "gtreqless;": '\U000022DB',
1073 "gtreqqless;": '\U00002A8C',
1074 "gtrless;": '\U00002277',
1075 "gtrsim;": '\U00002273',
1076 "hArr;": '\U000021D4',
1077 "hairsp;": '\U0000200A',
1078 "half;": '\U000000BD',
1079 "hamilt;": '\U0000210B',
1080 "hardcy;": '\U0000044A',
1081 "harr;": '\U00002194',
1082 "harrcir;": '\U00002948',
1083 "harrw;": '\U000021AD',
1084 "hbar;": '\U0000210F',
1085 "hcirc;": '\U00000125',
1086 "hearts;": '\U00002665',
1087 "heartsuit;": '\U00002665',
1088 "hellip;": '\U00002026',
1089 "hercon;": '\U000022B9',
1090 "hfr;": '\U0001D525',
1091 "hksearow;": '\U00002925',
1092 "hkswarow;": '\U00002926',
1093 "hoarr;": '\U000021FF',
1094 "homtht;": '\U0000223B',
1095 "hookleftarrow;": '\U000021A9',
1096 "hookrightarrow;": '\U000021AA',
1097 "hopf;": '\U0001D559',
1098 "horbar;": '\U00002015',
1099 "hscr;": '\U0001D4BD',
1100 "hslash;": '\U0000210F',
1101 "hstrok;": '\U00000127',
1102 "hybull;": '\U00002043',
1103 "hyphen;": '\U00002010',
1104 "iacute;": '\U000000ED',
1105 "ic;": '\U00002063',
1106 "icirc;": '\U000000EE',
1107 "icy;": '\U00000438',
1108 "iecy;": '\U00000435',
1109 "iexcl;": '\U000000A1',
1110 "iff;": '\U000021D4',
1111 "ifr;": '\U0001D526',
1112 "igrave;": '\U000000EC',
1113 "ii;": '\U00002148',
1114 "iiiint;": '\U00002A0C',
1115 "iiint;": '\U0000222D',
1116 "iinfin;": '\U000029DC',
1117 "iiota;": '\U00002129',
1118 "ijlig;": '\U00000133',
1119 "imacr;": '\U0000012B',
1120 "image;": '\U00002111',
1121 "imagline;": '\U00002110',
1122 "imagpart;": '\U00002111',
1123 "imath;": '\U00000131',
1124 "imof;": '\U000022B7',
1125 "imped;": '\U000001B5',
1126 "in;": '\U00002208',
1127 "incare;": '\U00002105',
1128 "infin;": '\U0000221E',
1129 "infintie;": '\U000029DD',
1130 "inodot;": '\U00000131',
1131 "int;": '\U0000222B',
1132 "intcal;": '\U000022BA',
1133 "integers;": '\U00002124',
1134 "intercal;": '\U000022BA',
1135 "intlarhk;": '\U00002A17',
1136 "intprod;": '\U00002A3C',
1137 "iocy;": '\U00000451',
1138 "iogon;": '\U0000012F',
1139 "iopf;": '\U0001D55A',
1140 "iota;": '\U000003B9',
1141 "iprod;": '\U00002A3C',
1142 "iquest;": '\U000000BF',
1143 "iscr;": '\U0001D4BE',
1144 "isin;": '\U00002208',
1145 "isinE;": '\U000022F9',
1146 "isindot;": '\U000022F5',
1147 "isins;": '\U000022F4',
1148 "isinsv;": '\U000022F3',
1149 "isinv;": '\U00002208',
1150 "it;": '\U00002062',
1151 "itilde;": '\U00000129',
1152 "iukcy;": '\U00000456',
1153 "iuml;": '\U000000EF',
1154 "jcirc;": '\U00000135',
1155 "jcy;": '\U00000439',
1156 "jfr;": '\U0001D527',
1157 "jmath;": '\U00000237',
1158 "jopf;": '\U0001D55B',
1159 "jscr;": '\U0001D4BF',
1160 "jsercy;": '\U00000458',
1161 "jukcy;": '\U00000454',
1162 "kappa;": '\U000003BA',
1163 "kappav;": '\U000003F0',
1164 "kcedil;": '\U00000137',
1165 "kcy;": '\U0000043A',
1166 "kfr;": '\U0001D528',
1167 "kgreen;": '\U00000138',
1168 "khcy;": '\U00000445',
1169 "kjcy;": '\U0000045C',
1170 "kopf;": '\U0001D55C',
1171 "kscr;": '\U0001D4C0',
1172 "lAarr;": '\U000021DA',
1173 "lArr;": '\U000021D0',
1174 "lAtail;": '\U0000291B',
1175 "lBarr;": '\U0000290E',
1176 "lE;": '\U00002266',
1177 "lEg;": '\U00002A8B',
1178 "lHar;": '\U00002962',
1179 "lacute;": '\U0000013A',
1180 "laemptyv;": '\U000029B4',
1181 "lagran;": '\U00002112',
1182 "lambda;": '\U000003BB',
1183 "lang;": '\U000027E8',
1184 "langd;": '\U00002991',
1185 "langle;": '\U000027E8',
1186 "lap;": '\U00002A85',
1187 "laquo;": '\U000000AB',
1188 "larr;": '\U00002190',
1189 "larrb;": '\U000021E4',
1190 "larrbfs;": '\U0000291F',
1191 "larrfs;": '\U0000291D',
1192 "larrhk;": '\U000021A9',
1193 "larrlp;": '\U000021AB',
1194 "larrpl;": '\U00002939',
1195 "larrsim;": '\U00002973',
1196 "larrtl;": '\U000021A2',
1197 "lat;": '\U00002AAB',
1198 "latail;": '\U00002919',
1199 "late;": '\U00002AAD',
1200 "lbarr;": '\U0000290C',
1201 "lbbrk;": '\U00002772',
1202 "lbrace;": '\U0000007B',
1203 "lbrack;": '\U0000005B',
1204 "lbrke;": '\U0000298B',
1205 "lbrksld;": '\U0000298F',
1206 "lbrkslu;": '\U0000298D',
1207 "lcaron;": '\U0000013E',
1208 "lcedil;": '\U0000013C',
1209 "lceil;": '\U00002308',
1210 "lcub;": '\U0000007B',
1211 "lcy;": '\U0000043B',
1212 "ldca;": '\U00002936',
1213 "ldquo;": '\U0000201C',
1214 "ldquor;": '\U0000201E',
1215 "ldrdhar;": '\U00002967',
1216 "ldrushar;": '\U0000294B',
1217 "ldsh;": '\U000021B2',
1218 "le;": '\U00002264',
1219 "leftarrow;": '\U00002190',
1220 "leftarrowtail;": '\U000021A2',
1221 "leftharpoondown;": '\U000021BD',
1222 "leftharpoonup;": '\U000021BC',
1223 "leftleftarrows;": '\U000021C7',
1224 "leftrightarrow;": '\U00002194',
1225 "leftrightarrows;": '\U000021C6',
1226 "leftrightharpoons;": '\U000021CB',
1227 "leftrightsquigarrow;": '\U000021AD',
1228 "leftthreetimes;": '\U000022CB',
1229 "leg;": '\U000022DA',
1230 "leq;": '\U00002264',
1231 "leqq;": '\U00002266',
1232 "leqslant;": '\U00002A7D',
1233 "les;": '\U00002A7D',
1234 "lescc;": '\U00002AA8',
1235 "lesdot;": '\U00002A7F',
1236 "lesdoto;": '\U00002A81',
1237 "lesdotor;": '\U00002A83',
1238 "lesges;": '\U00002A93',
1239 "lessapprox;": '\U00002A85',
1240 "lessdot;": '\U000022D6',
1241 "lesseqgtr;": '\U000022DA',
1242 "lesseqqgtr;": '\U00002A8B',
1243 "lessgtr;": '\U00002276',
1244 "lesssim;": '\U00002272',
1245 "lfisht;": '\U0000297C',
1246 "lfloor;": '\U0000230A',
1247 "lfr;": '\U0001D529',
1248 "lg;": '\U00002276',
1249 "lgE;": '\U00002A91',
1250 "lhard;": '\U000021BD',
1251 "lharu;": '\U000021BC',
1252 "lharul;": '\U0000296A',
1253 "lhblk;": '\U00002584',
1254 "ljcy;": '\U00000459',
1255 "ll;": '\U0000226A',
1256 "llarr;": '\U000021C7',
1257 "llcorner;": '\U0000231E',
1258 "llhard;": '\U0000296B',
1259 "lltri;": '\U000025FA',
1260 "lmidot;": '\U00000140',
1261 "lmoust;": '\U000023B0',
1262 "lmoustache;": '\U000023B0',
1263 "lnE;": '\U00002268',
1264 "lnap;": '\U00002A89',
1265 "lnapprox;": '\U00002A89',
1266 "lne;": '\U00002A87',
1267 "lneq;": '\U00002A87',
1268 "lneqq;": '\U00002268',
1269 "lnsim;": '\U000022E6',
1270 "loang;": '\U000027EC',
1271 "loarr;": '\U000021FD',
1272 "lobrk;": '\U000027E6',
1273 "longleftarrow;": '\U000027F5',
1274 "longleftrightarrow;": '\U000027F7',
1275 "longmapsto;": '\U000027FC',
1276 "longrightarrow;": '\U000027F6',
1277 "looparrowleft;": '\U000021AB',
1278 "looparrowright;": '\U000021AC',
1279 "lopar;": '\U00002985',
1280 "lopf;": '\U0001D55D',
1281 "loplus;": '\U00002A2D',
1282 "lotimes;": '\U00002A34',
1283 "lowast;": '\U00002217',
1284 "lowbar;": '\U0000005F',
1285 "loz;": '\U000025CA',
1286 "lozenge;": '\U000025CA',
1287 "lozf;": '\U000029EB',
1288 "lpar;": '\U00000028',
1289 "lparlt;": '\U00002993',
1290 "lrarr;": '\U000021C6',
1291 "lrcorner;": '\U0000231F',
1292 "lrhar;": '\U000021CB',
1293 "lrhard;": '\U0000296D',
1294 "lrm;": '\U0000200E',
1295 "lrtri;": '\U000022BF',
1296 "lsaquo;": '\U00002039',
1297 "lscr;": '\U0001D4C1',
1298 "lsh;": '\U000021B0',
1299 "lsim;": '\U00002272',
1300 "lsime;": '\U00002A8D',
1301 "lsimg;": '\U00002A8F',
1302 "lsqb;": '\U0000005B',
1303 "lsquo;": '\U00002018',
1304 "lsquor;": '\U0000201A',
1305 "lstrok;": '\U00000142',
1306 "lt;": '\U0000003C',
1307 "ltcc;": '\U00002AA6',
1308 "ltcir;": '\U00002A79',
1309 "ltdot;": '\U000022D6',
1310 "lthree;": '\U000022CB',
1311 "ltimes;": '\U000022C9',
1312 "ltlarr;": '\U00002976',
1313 "ltquest;": '\U00002A7B',
1314 "ltrPar;": '\U00002996',
1315 "ltri;": '\U000025C3',
1316 "ltrie;": '\U000022B4',
1317 "ltrif;": '\U000025C2',
1318 "lurdshar;": '\U0000294A',
1319 "luruhar;": '\U00002966',
1320 "mDDot;": '\U0000223A',
1321 "macr;": '\U000000AF',
1322 "male;": '\U00002642',
1323 "malt;": '\U00002720',
1324 "maltese;": '\U00002720',
1325 "map;": '\U000021A6',
1326 "mapsto;": '\U000021A6',
1327 "mapstodown;": '\U000021A7',
1328 "mapstoleft;": '\U000021A4',
1329 "mapstoup;": '\U000021A5',
1330 "marker;": '\U000025AE',
1331 "mcomma;": '\U00002A29',
1332 "mcy;": '\U0000043C',
1333 "mdash;": '\U00002014',
1334 "measuredangle;": '\U00002221',
1335 "mfr;": '\U0001D52A',
1336 "mho;": '\U00002127',
1337 "micro;": '\U000000B5',
1338 "mid;": '\U00002223',
1339 "midast;": '\U0000002A',
1340 "midcir;": '\U00002AF0',
1341 "middot;": '\U000000B7',
1342 "minus;": '\U00002212',
1343 "minusb;": '\U0000229F',
1344 "minusd;": '\U00002238',
1345 "minusdu;": '\U00002A2A',
1346 "mlcp;": '\U00002ADB',
1347 "mldr;": '\U00002026',
1348 "mnplus;": '\U00002213',
1349 "models;": '\U000022A7',
1350 "mopf;": '\U0001D55E',
1351 "mp;": '\U00002213',
1352 "mscr;": '\U0001D4C2',
1353 "mstpos;": '\U0000223E',
1354 "mu;": '\U000003BC',
1355 "multimap;": '\U000022B8',
1356 "mumap;": '\U000022B8',
1357 "nLeftarrow;": '\U000021CD',
1358 "nLeftrightarrow;": '\U000021CE',
1359 "nRightarrow;": '\U000021CF',
1360 "nVDash;": '\U000022AF',
1361 "nVdash;": '\U000022AE',
1362 "nabla;": '\U00002207',
1363 "nacute;": '\U00000144',
1364 "nap;": '\U00002249',
1365 "napos;": '\U00000149',
1366 "napprox;": '\U00002249',
1367 "natur;": '\U0000266E',
1368 "natural;": '\U0000266E',
1369 "naturals;": '\U00002115',
1370 "nbsp;": '\U000000A0',
1371 "ncap;": '\U00002A43',
1372 "ncaron;": '\U00000148',
1373 "ncedil;": '\U00000146',
1374 "ncong;": '\U00002247',
1375 "ncup;": '\U00002A42',
1376 "ncy;": '\U0000043D',
1377 "ndash;": '\U00002013',
1378 "ne;": '\U00002260',
1379 "neArr;": '\U000021D7',
1380 "nearhk;": '\U00002924',
1381 "nearr;": '\U00002197',
1382 "nearrow;": '\U00002197',
1383 "nequiv;": '\U00002262',
1384 "nesear;": '\U00002928',
1385 "nexist;": '\U00002204',
1386 "nexists;": '\U00002204',
1387 "nfr;": '\U0001D52B',
1388 "nge;": '\U00002271',
1389 "ngeq;": '\U00002271',
1390 "ngsim;": '\U00002275',
1391 "ngt;": '\U0000226F',
1392 "ngtr;": '\U0000226F',
1393 "nhArr;": '\U000021CE',
1394 "nharr;": '\U000021AE',
1395 "nhpar;": '\U00002AF2',
1396 "ni;": '\U0000220B',
1397 "nis;": '\U000022FC',
1398 "nisd;": '\U000022FA',
1399 "niv;": '\U0000220B',
1400 "njcy;": '\U0000045A',
1401 "nlArr;": '\U000021CD',
1402 "nlarr;": '\U0000219A',
1403 "nldr;": '\U00002025',
1404 "nle;": '\U00002270',
1405 "nleftarrow;": '\U0000219A',
1406 "nleftrightarrow;": '\U000021AE',
1407 "nleq;": '\U00002270',
1408 "nless;": '\U0000226E',
1409 "nlsim;": '\U00002274',
1410 "nlt;": '\U0000226E',
1411 "nltri;": '\U000022EA',
1412 "nltrie;": '\U000022EC',
1413 "nmid;": '\U00002224',
1414 "nopf;": '\U0001D55F',
1415 "not;": '\U000000AC',
1416 "notin;": '\U00002209',
1417 "notinva;": '\U00002209',
1418 "notinvb;": '\U000022F7',
1419 "notinvc;": '\U000022F6',
1420 "notni;": '\U0000220C',
1421 "notniva;": '\U0000220C',
1422 "notnivb;": '\U000022FE',
1423 "notnivc;": '\U000022FD',
1424 "npar;": '\U00002226',
1425 "nparallel;": '\U00002226',
1426 "npolint;": '\U00002A14',
1427 "npr;": '\U00002280',
1428 "nprcue;": '\U000022E0',
1429 "nprec;": '\U00002280',
1430 "nrArr;": '\U000021CF',
1431 "nrarr;": '\U0000219B',
1432 "nrightarrow;": '\U0000219B',
1433 "nrtri;": '\U000022EB',
1434 "nrtrie;": '\U000022ED',
1435 "nsc;": '\U00002281',
1436 "nsccue;": '\U000022E1',
1437 "nscr;": '\U0001D4C3',
1438 "nshortmid;": '\U00002224',
1439 "nshortparallel;": '\U00002226',
1440 "nsim;": '\U00002241',
1441 "nsime;": '\U00002244',
1442 "nsimeq;": '\U00002244',
1443 "nsmid;": '\U00002224',
1444 "nspar;": '\U00002226',
1445 "nsqsube;": '\U000022E2',
1446 "nsqsupe;": '\U000022E3',
1447 "nsub;": '\U00002284',
1448 "nsube;": '\U00002288',
1449 "nsubseteq;": '\U00002288',
1450 "nsucc;": '\U00002281',
1451 "nsup;": '\U00002285',
1452 "nsupe;": '\U00002289',
1453 "nsupseteq;": '\U00002289',
1454 "ntgl;": '\U00002279',
1455 "ntilde;": '\U000000F1',
1456 "ntlg;": '\U00002278',
1457 "ntriangleleft;": '\U000022EA',
1458 "ntrianglelefteq;": '\U000022EC',
1459 "ntriangleright;": '\U000022EB',
1460 "ntrianglerighteq;": '\U000022ED',
1461 "nu;": '\U000003BD',
1462 "num;": '\U00000023',
1463 "numero;": '\U00002116',
1464 "numsp;": '\U00002007',
1465 "nvDash;": '\U000022AD',
1466 "nvHarr;": '\U00002904',
1467 "nvdash;": '\U000022AC',
1468 "nvinfin;": '\U000029DE',
1469 "nvlArr;": '\U00002902',
1470 "nvrArr;": '\U00002903',
1471 "nwArr;": '\U000021D6',
1472 "nwarhk;": '\U00002923',
1473 "nwarr;": '\U00002196',
1474 "nwarrow;": '\U00002196',
1475 "nwnear;": '\U00002927',
1476 "oS;": '\U000024C8',
1477 "oacute;": '\U000000F3',
1478 "oast;": '\U0000229B',
1479 "ocir;": '\U0000229A',
1480 "ocirc;": '\U000000F4',
1481 "ocy;": '\U0000043E',
1482 "odash;": '\U0000229D',
1483 "odblac;": '\U00000151',
1484 "odiv;": '\U00002A38',
1485 "odot;": '\U00002299',
1486 "odsold;": '\U000029BC',
1487 "oelig;": '\U00000153',
1488 "ofcir;": '\U000029BF',
1489 "ofr;": '\U0001D52C',
1490 "ogon;": '\U000002DB',
1491 "ograve;": '\U000000F2',
1492 "ogt;": '\U000029C1',
1493 "ohbar;": '\U000029B5',
1494 "ohm;": '\U000003A9',
1495 "oint;": '\U0000222E',
1496 "olarr;": '\U000021BA',
1497 "olcir;": '\U000029BE',
1498 "olcross;": '\U000029BB',
1499 "oline;": '\U0000203E',
1500 "olt;": '\U000029C0',
1501 "omacr;": '\U0000014D',
1502 "omega;": '\U000003C9',
1503 "omicron;": '\U000003BF',
1504 "omid;": '\U000029B6',
1505 "ominus;": '\U00002296',
1506 "oopf;": '\U0001D560',
1507 "opar;": '\U000029B7',
1508 "operp;": '\U000029B9',
1509 "oplus;": '\U00002295',
1510 "or;": '\U00002228',
1511 "orarr;": '\U000021BB',
1512 "ord;": '\U00002A5D',
1513 "order;": '\U00002134',
1514 "orderof;": '\U00002134',
1515 "ordf;": '\U000000AA',
1516 "ordm;": '\U000000BA',
1517 "origof;": '\U000022B6',
1518 "oror;": '\U00002A56',
1519 "orslope;": '\U00002A57',
1520 "orv;": '\U00002A5B',
1521 "oscr;": '\U00002134',
1522 "oslash;": '\U000000F8',
1523 "osol;": '\U00002298',
1524 "otilde;": '\U000000F5',
1525 "otimes;": '\U00002297',
1526 "otimesas;": '\U00002A36',
1527 "ouml;": '\U000000F6',
1528 "ovbar;": '\U0000233D',
1529 "par;": '\U00002225',
1530 "para;": '\U000000B6',
1531 "parallel;": '\U00002225',
1532 "parsim;": '\U00002AF3',
1533 "parsl;": '\U00002AFD',
1534 "part;": '\U00002202',
1535 "pcy;": '\U0000043F',
1536 "percnt;": '\U00000025',
1537 "period;": '\U0000002E',
1538 "permil;": '\U00002030',
1539 "perp;": '\U000022A5',
1540 "pertenk;": '\U00002031',
1541 "pfr;": '\U0001D52D',
1542 "phi;": '\U000003C6',
1543 "phiv;": '\U000003D5',
1544 "phmmat;": '\U00002133',
1545 "phone;": '\U0000260E',
1546 "pi;": '\U000003C0',
1547 "pitchfork;": '\U000022D4',
1548 "piv;": '\U000003D6',
1549 "planck;": '\U0000210F',
1550 "planckh;": '\U0000210E',
1551 "plankv;": '\U0000210F',
1552 "plus;": '\U0000002B',
1553 "plusacir;": '\U00002A23',
1554 "plusb;": '\U0000229E',
1555 "pluscir;": '\U00002A22',
1556 "plusdo;": '\U00002214',
1557 "plusdu;": '\U00002A25',
1558 "pluse;": '\U00002A72',
1559 "plusmn;": '\U000000B1',
1560 "plussim;": '\U00002A26',
1561 "plustwo;": '\U00002A27',
1562 "pm;": '\U000000B1',
1563 "pointint;": '\U00002A15',
1564 "popf;": '\U0001D561',
1565 "pound;": '\U000000A3',
1566 "pr;": '\U0000227A',
1567 "prE;": '\U00002AB3',
1568 "prap;": '\U00002AB7',
1569 "prcue;": '\U0000227C',
1570 "pre;": '\U00002AAF',
1571 "prec;": '\U0000227A',
1572 "precapprox;": '\U00002AB7',
1573 "preccurlyeq;": '\U0000227C',
1574 "preceq;": '\U00002AAF',
1575 "precnapprox;": '\U00002AB9',
1576 "precneqq;": '\U00002AB5',
1577 "precnsim;": '\U000022E8',
1578 "precsim;": '\U0000227E',
1579 "prime;": '\U00002032',
1580 "primes;": '\U00002119',
1581 "prnE;": '\U00002AB5',
1582 "prnap;": '\U00002AB9',
1583 "prnsim;": '\U000022E8',
1584 "prod;": '\U0000220F',
1585 "profalar;": '\U0000232E',
1586 "profline;": '\U00002312',
1587 "profsurf;": '\U00002313',
1588 "prop;": '\U0000221D',
1589 "propto;": '\U0000221D',
1590 "prsim;": '\U0000227E',
1591 "prurel;": '\U000022B0',
1592 "pscr;": '\U0001D4C5',
1593 "psi;": '\U000003C8',
1594 "puncsp;": '\U00002008',
1595 "qfr;": '\U0001D52E',
1596 "qint;": '\U00002A0C',
1597 "qopf;": '\U0001D562',
1598 "qprime;": '\U00002057',
1599 "qscr;": '\U0001D4C6',
1600 "quaternions;": '\U0000210D',
1601 "quatint;": '\U00002A16',
1602 "quest;": '\U0000003F',
1603 "questeq;": '\U0000225F',
1604 "quot;": '\U00000022',
1605 "rAarr;": '\U000021DB',
1606 "rArr;": '\U000021D2',
1607 "rAtail;": '\U0000291C',
1608 "rBarr;": '\U0000290F',
1609 "rHar;": '\U00002964',
1610 "racute;": '\U00000155',
1611 "radic;": '\U0000221A',
1612 "raemptyv;": '\U000029B3',
1613 "rang;": '\U000027E9',
1614 "rangd;": '\U00002992',
1615 "range;": '\U000029A5',
1616 "rangle;": '\U000027E9',
1617 "raquo;": '\U000000BB',
1618 "rarr;": '\U00002192',
1619 "rarrap;": '\U00002975',
1620 "rarrb;": '\U000021E5',
1621 "rarrbfs;": '\U00002920',
1622 "rarrc;": '\U00002933',
1623 "rarrfs;": '\U0000291E',
1624 "rarrhk;": '\U000021AA',
1625 "rarrlp;": '\U000021AC',
1626 "rarrpl;": '\U00002945',
1627 "rarrsim;": '\U00002974',
1628 "rarrtl;": '\U000021A3',
1629 "rarrw;": '\U0000219D',
1630 "ratail;": '\U0000291A',
1631 "ratio;": '\U00002236',
1632 "rationals;": '\U0000211A',
1633 "rbarr;": '\U0000290D',
1634 "rbbrk;": '\U00002773',
1635 "rbrace;": '\U0000007D',
1636 "rbrack;": '\U0000005D',
1637 "rbrke;": '\U0000298C',
1638 "rbrksld;": '\U0000298E',
1639 "rbrkslu;": '\U00002990',
1640 "rcaron;": '\U00000159',
1641 "rcedil;": '\U00000157',
1642 "rceil;": '\U00002309',
1643 "rcub;": '\U0000007D',
1644 "rcy;": '\U00000440',
1645 "rdca;": '\U00002937',
1646 "rdldhar;": '\U00002969',
1647 "rdquo;": '\U0000201D',
1648 "rdquor;": '\U0000201D',
1649 "rdsh;": '\U000021B3',
1650 "real;": '\U0000211C',
1651 "realine;": '\U0000211B',
1652 "realpart;": '\U0000211C',
1653 "reals;": '\U0000211D',
1654 "rect;": '\U000025AD',
1655 "reg;": '\U000000AE',
1656 "rfisht;": '\U0000297D',
1657 "rfloor;": '\U0000230B',
1658 "rfr;": '\U0001D52F',
1659 "rhard;": '\U000021C1',
1660 "rharu;": '\U000021C0',
1661 "rharul;": '\U0000296C',
1662 "rho;": '\U000003C1',
1663 "rhov;": '\U000003F1',
1664 "rightarrow;": '\U00002192',
1665 "rightarrowtail;": '\U000021A3',
1666 "rightharpoondown;": '\U000021C1',
1667 "rightharpoonup;": '\U000021C0',
1668 "rightleftarrows;": '\U000021C4',
1669 "rightleftharpoons;": '\U000021CC',
1670 "rightrightarrows;": '\U000021C9',
1671 "rightsquigarrow;": '\U0000219D',
1672 "rightthreetimes;": '\U000022CC',
1673 "ring;": '\U000002DA',
1674 "risingdotseq;": '\U00002253',
1675 "rlarr;": '\U000021C4',
1676 "rlhar;": '\U000021CC',
1677 "rlm;": '\U0000200F',
1678 "rmoust;": '\U000023B1',
1679 "rmoustache;": '\U000023B1',
1680 "rnmid;": '\U00002AEE',
1681 "roang;": '\U000027ED',
1682 "roarr;": '\U000021FE',
1683 "robrk;": '\U000027E7',
1684 "ropar;": '\U00002986',
1685 "ropf;": '\U0001D563',
1686 "roplus;": '\U00002A2E',
1687 "rotimes;": '\U00002A35',
1688 "rpar;": '\U00000029',
1689 "rpargt;": '\U00002994',
1690 "rppolint;": '\U00002A12',
1691 "rrarr;": '\U000021C9',
1692 "rsaquo;": '\U0000203A',
1693 "rscr;": '\U0001D4C7',
1694 "rsh;": '\U000021B1',
1695 "rsqb;": '\U0000005D',
1696 "rsquo;": '\U00002019',
1697 "rsquor;": '\U00002019',
1698 "rthree;": '\U000022CC',
1699 "rtimes;": '\U000022CA',
1700 "rtri;": '\U000025B9',
1701 "rtrie;": '\U000022B5',
1702 "rtrif;": '\U000025B8',
1703 "rtriltri;": '\U000029CE',
1704 "ruluhar;": '\U00002968',
1705 "rx;": '\U0000211E',
1706 "sacute;": '\U0000015B',
1707 "sbquo;": '\U0000201A',
1708 "sc;": '\U0000227B',
1709 "scE;": '\U00002AB4',
1710 "scap;": '\U00002AB8',
1711 "scaron;": '\U00000161',
1712 "sccue;": '\U0000227D',
1713 "sce;": '\U00002AB0',
1714 "scedil;": '\U0000015F',
1715 "scirc;": '\U0000015D',
1716 "scnE;": '\U00002AB6',
1717 "scnap;": '\U00002ABA',
1718 "scnsim;": '\U000022E9',
1719 "scpolint;": '\U00002A13',
1720 "scsim;": '\U0000227F',
1721 "scy;": '\U00000441',
1722 "sdot;": '\U000022C5',
1723 "sdotb;": '\U000022A1',
1724 "sdote;": '\U00002A66',
1725 "seArr;": '\U000021D8',
1726 "searhk;": '\U00002925',
1727 "searr;": '\U00002198',
1728 "searrow;": '\U00002198',
1729 "sect;": '\U000000A7',
1730 "semi;": '\U0000003B',
1731 "seswar;": '\U00002929',
1732 "setminus;": '\U00002216',
1733 "setmn;": '\U00002216',
1734 "sext;": '\U00002736',
1735 "sfr;": '\U0001D530',
1736 "sfrown;": '\U00002322',
1737 "sharp;": '\U0000266F',
1738 "shchcy;": '\U00000449',
1739 "shcy;": '\U00000448',
1740 "shortmid;": '\U00002223',
1741 "shortparallel;": '\U00002225',
1742 "shy;": '\U000000AD',
1743 "sigma;": '\U000003C3',
1744 "sigmaf;": '\U000003C2',
1745 "sigmav;": '\U000003C2',
1746 "sim;": '\U0000223C',
1747 "simdot;": '\U00002A6A',
1748 "sime;": '\U00002243',
1749 "simeq;": '\U00002243',
1750 "simg;": '\U00002A9E',
1751 "simgE;": '\U00002AA0',
1752 "siml;": '\U00002A9D',
1753 "simlE;": '\U00002A9F',
1754 "simne;": '\U00002246',
1755 "simplus;": '\U00002A24',
1756 "simrarr;": '\U00002972',
1757 "slarr;": '\U00002190',
1758 "smallsetminus;": '\U00002216',
1759 "smashp;": '\U00002A33',
1760 "smeparsl;": '\U000029E4',
1761 "smid;": '\U00002223',
1762 "smile;": '\U00002323',
1763 "smt;": '\U00002AAA',
1764 "smte;": '\U00002AAC',
1765 "softcy;": '\U0000044C',
1766 "sol;": '\U0000002F',
1767 "solb;": '\U000029C4',
1768 "solbar;": '\U0000233F',
1769 "sopf;": '\U0001D564',
1770 "spades;": '\U00002660',
1771 "spadesuit;": '\U00002660',
1772 "spar;": '\U00002225',
1773 "sqcap;": '\U00002293',
1774 "sqcup;": '\U00002294',
1775 "sqsub;": '\U0000228F',
1776 "sqsube;": '\U00002291',
1777 "sqsubset;": '\U0000228F',
1778 "sqsubseteq;": '\U00002291',
1779 "sqsup;": '\U00002290',
1780 "sqsupe;": '\U00002292',
1781 "sqsupset;": '\U00002290',
1782 "sqsupseteq;": '\U00002292',
1783 "squ;": '\U000025A1',
1784 "square;": '\U000025A1',
1785 "squarf;": '\U000025AA',
1786 "squf;": '\U000025AA',
1787 "srarr;": '\U00002192',
1788 "sscr;": '\U0001D4C8',
1789 "ssetmn;": '\U00002216',
1790 "ssmile;": '\U00002323',
1791 "sstarf;": '\U000022C6',
1792 "star;": '\U00002606',
1793 "starf;": '\U00002605',
1794 "straightepsilon;": '\U000003F5',
1795 "straightphi;": '\U000003D5',
1796 "strns;": '\U000000AF',
1797 "sub;": '\U00002282',
1798 "subE;": '\U00002AC5',
1799 "subdot;": '\U00002ABD',
1800 "sube;": '\U00002286',
1801 "subedot;": '\U00002AC3',
1802 "submult;": '\U00002AC1',
1803 "subnE;": '\U00002ACB',
1804 "subne;": '\U0000228A',
1805 "subplus;": '\U00002ABF',
1806 "subrarr;": '\U00002979',
1807 "subset;": '\U00002282',
1808 "subseteq;": '\U00002286',
1809 "subseteqq;": '\U00002AC5',
1810 "subsetneq;": '\U0000228A',
1811 "subsetneqq;": '\U00002ACB',
1812 "subsim;": '\U00002AC7',
1813 "subsub;": '\U00002AD5',
1814 "subsup;": '\U00002AD3',
1815 "succ;": '\U0000227B',
1816 "succapprox;": '\U00002AB8',
1817 "succcurlyeq;": '\U0000227D',
1818 "succeq;": '\U00002AB0',
1819 "succnapprox;": '\U00002ABA',
1820 "succneqq;": '\U00002AB6',
1821 "succnsim;": '\U000022E9',
1822 "succsim;": '\U0000227F',
1823 "sum;": '\U00002211',
1824 "sung;": '\U0000266A',
1825 "sup;": '\U00002283',
1826 "sup1;": '\U000000B9',
1827 "sup2;": '\U000000B2',
1828 "sup3;": '\U000000B3',
1829 "supE;": '\U00002AC6',
1830 "supdot;": '\U00002ABE',
1831 "supdsub;": '\U00002AD8',
1832 "supe;": '\U00002287',
1833 "supedot;": '\U00002AC4',
1834 "suphsol;": '\U000027C9',
1835 "suphsub;": '\U00002AD7',
1836 "suplarr;": '\U0000297B',
1837 "supmult;": '\U00002AC2',
1838 "supnE;": '\U00002ACC',
1839 "supne;": '\U0000228B',
1840 "supplus;": '\U00002AC0',
1841 "supset;": '\U00002283',
1842 "supseteq;": '\U00002287',
1843 "supseteqq;": '\U00002AC6',
1844 "supsetneq;": '\U0000228B',
1845 "supsetneqq;": '\U00002ACC',
1846 "supsim;": '\U00002AC8',
1847 "supsub;": '\U00002AD4',
1848 "supsup;": '\U00002AD6',
1849 "swArr;": '\U000021D9',
1850 "swarhk;": '\U00002926',
1851 "swarr;": '\U00002199',
1852 "swarrow;": '\U00002199',
1853 "swnwar;": '\U0000292A',
1854 "szlig;": '\U000000DF',
1855 "target;": '\U00002316',
1856 "tau;": '\U000003C4',
1857 "tbrk;": '\U000023B4',
1858 "tcaron;": '\U00000165',
1859 "tcedil;": '\U00000163',
1860 "tcy;": '\U00000442',
1861 "tdot;": '\U000020DB',
1862 "telrec;": '\U00002315',
1863 "tfr;": '\U0001D531',
1864 "there4;": '\U00002234',
1865 "therefore;": '\U00002234',
1866 "theta;": '\U000003B8',
1867 "thetasym;": '\U000003D1',
1868 "thetav;": '\U000003D1',
1869 "thickapprox;": '\U00002248',
1870 "thicksim;": '\U0000223C',
1871 "thinsp;": '\U00002009',
1872 "thkap;": '\U00002248',
1873 "thksim;": '\U0000223C',
1874 "thorn;": '\U000000FE',
1875 "tilde;": '\U000002DC',
1876 "times;": '\U000000D7',
1877 "timesb;": '\U000022A0',
1878 "timesbar;": '\U00002A31',
1879 "timesd;": '\U00002A30',
1880 "tint;": '\U0000222D',
1881 "toea;": '\U00002928',
1882 "top;": '\U000022A4',
1883 "topbot;": '\U00002336',
1884 "topcir;": '\U00002AF1',
1885 "topf;": '\U0001D565',
1886 "topfork;": '\U00002ADA',
1887 "tosa;": '\U00002929',
1888 "tprime;": '\U00002034',
1889 "trade;": '\U00002122',
1890 "triangle;": '\U000025B5',
1891 "triangledown;": '\U000025BF',
1892 "triangleleft;": '\U000025C3',
1893 "trianglelefteq;": '\U000022B4',
1894 "triangleq;": '\U0000225C',
1895 "triangleright;": '\U000025B9',
1896 "trianglerighteq;": '\U000022B5',
1897 "tridot;": '\U000025EC',
1898 "trie;": '\U0000225C',
1899 "triminus;": '\U00002A3A',
1900 "triplus;": '\U00002A39',
1901 "trisb;": '\U000029CD',
1902 "tritime;": '\U00002A3B',
1903 "trpezium;": '\U000023E2',
1904 "tscr;": '\U0001D4C9',
1905 "tscy;": '\U00000446',
1906 "tshcy;": '\U0000045B',
1907 "tstrok;": '\U00000167',
1908 "twixt;": '\U0000226C',
1909 "twoheadleftarrow;": '\U0000219E',
1910 "twoheadrightarrow;": '\U000021A0',
1911 "uArr;": '\U000021D1',
1912 "uHar;": '\U00002963',
1913 "uacute;": '\U000000FA',
1914 "uarr;": '\U00002191',
1915 "ubrcy;": '\U0000045E',
1916 "ubreve;": '\U0000016D',
1917 "ucirc;": '\U000000FB',
1918 "ucy;": '\U00000443',
1919 "udarr;": '\U000021C5',
1920 "udblac;": '\U00000171',
1921 "udhar;": '\U0000296E',
1922 "ufisht;": '\U0000297E',
1923 "ufr;": '\U0001D532',
1924 "ugrave;": '\U000000F9',
1925 "uharl;": '\U000021BF',
1926 "uharr;": '\U000021BE',
1927 "uhblk;": '\U00002580',
1928 "ulcorn;": '\U0000231C',
1929 "ulcorner;": '\U0000231C',
1930 "ulcrop;": '\U0000230F',
1931 "ultri;": '\U000025F8',
1932 "umacr;": '\U0000016B',
1933 "uml;": '\U000000A8',
1934 "uogon;": '\U00000173',
1935 "uopf;": '\U0001D566',
1936 "uparrow;": '\U00002191',
1937 "updownarrow;": '\U00002195',
1938 "upharpoonleft;": '\U000021BF',
1939 "upharpoonright;": '\U000021BE',
1940 "uplus;": '\U0000228E',
1941 "upsi;": '\U000003C5',
1942 "upsih;": '\U000003D2',
1943 "upsilon;": '\U000003C5',
1944 "upuparrows;": '\U000021C8',
1945 "urcorn;": '\U0000231D',
1946 "urcorner;": '\U0000231D',
1947 "urcrop;": '\U0000230E',
1948 "uring;": '\U0000016F',
1949 "urtri;": '\U000025F9',
1950 "uscr;": '\U0001D4CA',
1951 "utdot;": '\U000022F0',
1952 "utilde;": '\U00000169',
1953 "utri;": '\U000025B5',
1954 "utrif;": '\U000025B4',
1955 "uuarr;": '\U000021C8',
1956 "uuml;": '\U000000FC',
1957 "uwangle;": '\U000029A7',
1958 "vArr;": '\U000021D5',
1959 "vBar;": '\U00002AE8',
1960 "vBarv;": '\U00002AE9',
1961 "vDash;": '\U000022A8',
1962 "vangrt;": '\U0000299C',
1963 "varepsilon;": '\U000003F5',
1964 "varkappa;": '\U000003F0',
1965 "varnothing;": '\U00002205',
1966 "varphi;": '\U000003D5',
1967 "varpi;": '\U000003D6',
1968 "varpropto;": '\U0000221D',
1969 "varr;": '\U00002195',
1970 "varrho;": '\U000003F1',
1971 "varsigma;": '\U000003C2',
1972 "vartheta;": '\U000003D1',
1973 "vartriangleleft;": '\U000022B2',
1974 "vartriangleright;": '\U000022B3',
1975 "vcy;": '\U00000432',
1976 "vdash;": '\U000022A2',
1977 "vee;": '\U00002228',
1978 "veebar;": '\U000022BB',
1979 "veeeq;": '\U0000225A',
1980 "vellip;": '\U000022EE',
1981 "verbar;": '\U0000007C',
1982 "vert;": '\U0000007C',
1983 "vfr;": '\U0001D533',
1984 "vltri;": '\U000022B2',
1985 "vopf;": '\U0001D567',
1986 "vprop;": '\U0000221D',
1987 "vrtri;": '\U000022B3',
1988 "vscr;": '\U0001D4CB',
1989 "vzigzag;": '\U0000299A',
1990 "wcirc;": '\U00000175',
1991 "wedbar;": '\U00002A5F',
1992 "wedge;": '\U00002227',
1993 "wedgeq;": '\U00002259',
1994 "weierp;": '\U00002118',
1995 "wfr;": '\U0001D534',
1996 "wopf;": '\U0001D568',
1997 "wp;": '\U00002118',
1998 "wr;": '\U00002240',
1999 "wreath;": '\U00002240',
2000 "wscr;": '\U0001D4CC',
2001 "xcap;": '\U000022C2',
2002 "xcirc;": '\U000025EF',
2003 "xcup;": '\U000022C3',
2004 "xdtri;": '\U000025BD',
2005 "xfr;": '\U0001D535',
2006 "xhArr;": '\U000027FA',
2007 "xharr;": '\U000027F7',
2008 "xi;": '\U000003BE',
2009 "xlArr;": '\U000027F8',
2010 "xlarr;": '\U000027F5',
2011 "xmap;": '\U000027FC',
2012 "xnis;": '\U000022FB',
2013 "xodot;": '\U00002A00',
2014 "xopf;": '\U0001D569',
2015 "xoplus;": '\U00002A01',
2016 "xotime;": '\U00002A02',
2017 "xrArr;": '\U000027F9',
2018 "xrarr;": '\U000027F6',
2019 "xscr;": '\U0001D4CD',
2020 "xsqcup;": '\U00002A06',
2021 "xuplus;": '\U00002A04',
2022 "xutri;": '\U000025B3',
2023 "xvee;": '\U000022C1',
2024 "xwedge;": '\U000022C0',
2025 "yacute;": '\U000000FD',
2026 "yacy;": '\U0000044F',
2027 "ycirc;": '\U00000177',
2028 "ycy;": '\U0000044B',
2029 "yen;": '\U000000A5',
2030 "yfr;": '\U0001D536',
2031 "yicy;": '\U00000457',
2032 "yopf;": '\U0001D56A',
2033 "yscr;": '\U0001D4CE',
2034 "yucy;": '\U0000044E',
2035 "yuml;": '\U000000FF',
2036 "zacute;": '\U0000017A',
2037 "zcaron;": '\U0000017E',
2038 "zcy;": '\U00000437',
2039 "zdot;": '\U0000017C',
2040 "zeetrf;": '\U00002128',
2041 "zeta;": '\U000003B6',
2042 "zfr;": '\U0001D537',
2043 "zhcy;": '\U00000436',
2044 "zigrarr;": '\U000021DD',
2045 "zopf;": '\U0001D56B',
2046 "zscr;": '\U0001D4CF',
2047 "zwj;": '\U0000200D',
2048 "zwnj;": '\U0000200C',
2049 "AElig": '\U000000C6',
2050 "AMP": '\U00000026',
2051 "Aacute": '\U000000C1',
2052 "Acirc": '\U000000C2',
2053 "Agrave": '\U000000C0',
2054 "Aring": '\U000000C5',
2055 "Atilde": '\U000000C3',
2056 "Auml": '\U000000C4',
2057 "COPY": '\U000000A9',
2058 "Ccedil": '\U000000C7',
2059 "ETH": '\U000000D0',
2060 "Eacute": '\U000000C9',
2061 "Ecirc": '\U000000CA',
2062 "Egrave": '\U000000C8',
2063 "Euml": '\U000000CB',
2064 "GT": '\U0000003E',
2065 "Iacute": '\U000000CD',
2066 "Icirc": '\U000000CE',
2067 "Igrave": '\U000000CC',
2068 "Iuml": '\U000000CF',
2069 "LT": '\U0000003C',
2070 "Ntilde": '\U000000D1',
2071 "Oacute": '\U000000D3',
2072 "Ocirc": '\U000000D4',
2073 "Ograve": '\U000000D2',
2074 "Oslash": '\U000000D8',
2075 "Otilde": '\U000000D5',
2076 "Ouml": '\U000000D6',
2077 "QUOT": '\U00000022',
2078 "REG": '\U000000AE',
2079 "THORN": '\U000000DE',
2080 "Uacute": '\U000000DA',
2081 "Ucirc": '\U000000DB',
2082 "Ugrave": '\U000000D9',
2083 "Uuml": '\U000000DC',
2084 "Yacute": '\U000000DD',
2085 "aacute": '\U000000E1',
2086 "acirc": '\U000000E2',
2087 "acute": '\U000000B4',
2088 "aelig": '\U000000E6',
2089 "agrave": '\U000000E0',
2090 "amp": '\U00000026',
2091 "aring": '\U000000E5',
2092 "atilde": '\U000000E3',
2093 "auml": '\U000000E4',
2094 "brvbar": '\U000000A6',
2095 "ccedil": '\U000000E7',
2096 "cedil": '\U000000B8',
2097 "cent": '\U000000A2',
2098 "copy": '\U000000A9',
2099 "curren": '\U000000A4',
2100 "deg": '\U000000B0',
2101 "divide": '\U000000F7',
2102 "eacute": '\U000000E9',
2103 "ecirc": '\U000000EA',
2104 "egrave": '\U000000E8',
2105 "eth": '\U000000F0',
2106 "euml": '\U000000EB',
2107 "frac12": '\U000000BD',
2108 "frac14": '\U000000BC',
2109 "frac34": '\U000000BE',
2110 "gt": '\U0000003E',
2111 "iacute": '\U000000ED',
2112 "icirc": '\U000000EE',
2113 "iexcl": '\U000000A1',
2114 "igrave": '\U000000EC',
2115 "iquest": '\U000000BF',
2116 "iuml": '\U000000EF',
2117 "laquo": '\U000000AB',
2118 "lt": '\U0000003C',
2119 "macr": '\U000000AF',
2120 "micro": '\U000000B5',
2121 "middot": '\U000000B7',
2122 "nbsp": '\U000000A0',
2123 "not": '\U000000AC',
2124 "ntilde": '\U000000F1',
2125 "oacute": '\U000000F3',
2126 "ocirc": '\U000000F4',
2127 "ograve": '\U000000F2',
2128 "ordf": '\U000000AA',
2129 "ordm": '\U000000BA',
2130 "oslash": '\U000000F8',
2131 "otilde": '\U000000F5',
2132 "ouml": '\U000000F6',
2133 "para": '\U000000B6',
2134 "plusmn": '\U000000B1',
2135 "pound": '\U000000A3',
2136 "quot": '\U00000022',
2137 "raquo": '\U000000BB',
2138 "reg": '\U000000AE',
2139 "sect": '\U000000A7',
2140 "shy": '\U000000AD',
2141 "sup1": '\U000000B9',
2142 "sup2": '\U000000B2',
2143 "sup3": '\U000000B3',
2144 "szlig": '\U000000DF',
2145 "thorn": '\U000000FE',
2146 "times": '\U000000D7',
2147 "uacute": '\U000000FA',
2148 "ucirc": '\U000000FB',
2149 "ugrave": '\U000000F9',
2150 "uml": '\U000000A8',
2151 "uuml": '\U000000FC',
2152 "yacute": '\U000000FD',
2153 "yen": '\U000000A5',
2154 "yuml": '\U000000FF',
2155}
2156
2157// HTML entities that are two unicode codepoints.
2158var entity2 = map[string][2]rune{
2159 // TODO(nigeltao): Handle replacements that are wider than their names.
2160 // "nLt;": {'\u226A', '\u20D2'},
2161 // "nGt;": {'\u226B', '\u20D2'},
2162 "NotEqualTilde;": {'\u2242', '\u0338'},
2163 "NotGreaterFullEqual;": {'\u2267', '\u0338'},
2164 "NotGreaterGreater;": {'\u226B', '\u0338'},
2165 "NotGreaterSlantEqual;": {'\u2A7E', '\u0338'},
2166 "NotHumpDownHump;": {'\u224E', '\u0338'},
2167 "NotHumpEqual;": {'\u224F', '\u0338'},
2168 "NotLeftTriangleBar;": {'\u29CF', '\u0338'},
2169 "NotLessLess;": {'\u226A', '\u0338'},
2170 "NotLessSlantEqual;": {'\u2A7D', '\u0338'},
2171 "NotNestedGreaterGreater;": {'\u2AA2', '\u0338'},
2172 "NotNestedLessLess;": {'\u2AA1', '\u0338'},
2173 "NotPrecedesEqual;": {'\u2AAF', '\u0338'},
2174 "NotRightTriangleBar;": {'\u29D0', '\u0338'},
2175 "NotSquareSubset;": {'\u228F', '\u0338'},
2176 "NotSquareSuperset;": {'\u2290', '\u0338'},
2177 "NotSubset;": {'\u2282', '\u20D2'},
2178 "NotSucceedsEqual;": {'\u2AB0', '\u0338'},
2179 "NotSucceedsTilde;": {'\u227F', '\u0338'},
2180 "NotSuperset;": {'\u2283', '\u20D2'},
2181 "ThickSpace;": {'\u205F', '\u200A'},
2182 "acE;": {'\u223E', '\u0333'},
2183 "bne;": {'\u003D', '\u20E5'},
2184 "bnequiv;": {'\u2261', '\u20E5'},
2185 "caps;": {'\u2229', '\uFE00'},
2186 "cups;": {'\u222A', '\uFE00'},
2187 "fjlig;": {'\u0066', '\u006A'},
2188 "gesl;": {'\u22DB', '\uFE00'},
2189 "gvertneqq;": {'\u2269', '\uFE00'},
2190 "gvnE;": {'\u2269', '\uFE00'},
2191 "lates;": {'\u2AAD', '\uFE00'},
2192 "lesg;": {'\u22DA', '\uFE00'},
2193 "lvertneqq;": {'\u2268', '\uFE00'},
2194 "lvnE;": {'\u2268', '\uFE00'},
2195 "nGg;": {'\u22D9', '\u0338'},
2196 "nGtv;": {'\u226B', '\u0338'},
2197 "nLl;": {'\u22D8', '\u0338'},
2198 "nLtv;": {'\u226A', '\u0338'},
2199 "nang;": {'\u2220', '\u20D2'},
2200 "napE;": {'\u2A70', '\u0338'},
2201 "napid;": {'\u224B', '\u0338'},
2202 "nbump;": {'\u224E', '\u0338'},
2203 "nbumpe;": {'\u224F', '\u0338'},
2204 "ncongdot;": {'\u2A6D', '\u0338'},
2205 "nedot;": {'\u2250', '\u0338'},
2206 "nesim;": {'\u2242', '\u0338'},
2207 "ngE;": {'\u2267', '\u0338'},
2208 "ngeqq;": {'\u2267', '\u0338'},
2209 "ngeqslant;": {'\u2A7E', '\u0338'},
2210 "nges;": {'\u2A7E', '\u0338'},
2211 "nlE;": {'\u2266', '\u0338'},
2212 "nleqq;": {'\u2266', '\u0338'},
2213 "nleqslant;": {'\u2A7D', '\u0338'},
2214 "nles;": {'\u2A7D', '\u0338'},
2215 "notinE;": {'\u22F9', '\u0338'},
2216 "notindot;": {'\u22F5', '\u0338'},
2217 "nparsl;": {'\u2AFD', '\u20E5'},
2218 "npart;": {'\u2202', '\u0338'},
2219 "npre;": {'\u2AAF', '\u0338'},
2220 "npreceq;": {'\u2AAF', '\u0338'},
2221 "nrarrc;": {'\u2933', '\u0338'},
2222 "nrarrw;": {'\u219D', '\u0338'},
2223 "nsce;": {'\u2AB0', '\u0338'},
2224 "nsubE;": {'\u2AC5', '\u0338'},
2225 "nsubset;": {'\u2282', '\u20D2'},
2226 "nsubseteqq;": {'\u2AC5', '\u0338'},
2227 "nsucceq;": {'\u2AB0', '\u0338'},
2228 "nsupE;": {'\u2AC6', '\u0338'},
2229 "nsupset;": {'\u2283', '\u20D2'},
2230 "nsupseteqq;": {'\u2AC6', '\u0338'},
2231 "nvap;": {'\u224D', '\u20D2'},
2232 "nvge;": {'\u2265', '\u20D2'},
2233 "nvgt;": {'\u003E', '\u20D2'},
2234 "nvle;": {'\u2264', '\u20D2'},
2235 "nvlt;": {'\u003C', '\u20D2'},
2236 "nvltrie;": {'\u22B4', '\u20D2'},
2237 "nvrtrie;": {'\u22B5', '\u20D2'},
2238 "nvsim;": {'\u223C', '\u20D2'},
2239 "race;": {'\u223D', '\u0331'},
2240 "smtes;": {'\u2AAC', '\uFE00'},
2241 "sqcaps;": {'\u2293', '\uFE00'},
2242 "sqcups;": {'\u2294', '\uFE00'},
2243 "varsubsetneq;": {'\u228A', '\uFE00'},
2244 "varsubsetneqq;": {'\u2ACB', '\uFE00'},
2245 "varsupsetneq;": {'\u228B', '\uFE00'},
2246 "varsupsetneqq;": {'\u2ACC', '\uFE00'},
2247 "vnsub;": {'\u2282', '\u20D2'},
2248 "vnsup;": {'\u2283', '\u20D2'},
2249 "vsubnE;": {'\u2ACB', '\uFE00'},
2250 "vsubne;": {'\u228A', '\uFE00'},
2251 "vsupnE;": {'\u2ACC', '\uFE00'},
2252 "vsupne;": {'\u228B', '\uFE00'},
2253}
diff --git a/vendor/golang.org/x/net/html/escape.go b/vendor/golang.org/x/net/html/escape.go
new file mode 100644
index 0000000..d856139
--- /dev/null
+++ b/vendor/golang.org/x/net/html/escape.go
@@ -0,0 +1,258 @@
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
5package html
6
7import (
8 "bytes"
9 "strings"
10 "unicode/utf8"
11)
12
13// These replacements permit compatibility with old numeric entities that
14// assumed Windows-1252 encoding.
15// https://html.spec.whatwg.org/multipage/syntax.html#consume-a-character-reference
16var replacementTable = [...]rune{
17 '\u20AC', // First entry is what 0x80 should be replaced with.
18 '\u0081',
19 '\u201A',
20 '\u0192',
21 '\u201E',
22 '\u2026',
23 '\u2020',
24 '\u2021',
25 '\u02C6',
26 '\u2030',
27 '\u0160',
28 '\u2039',
29 '\u0152',
30 '\u008D',
31 '\u017D',
32 '\u008F',
33 '\u0090',
34 '\u2018',
35 '\u2019',
36 '\u201C',
37 '\u201D',
38 '\u2022',
39 '\u2013',
40 '\u2014',
41 '\u02DC',
42 '\u2122',
43 '\u0161',
44 '\u203A',
45 '\u0153',
46 '\u009D',
47 '\u017E',
48 '\u0178', // Last entry is 0x9F.
49 // 0x00->'\uFFFD' is handled programmatically.
50 // 0x0D->'\u000D' is a no-op.
51}
52
53// unescapeEntity reads an entity like "&lt;" from b[src:] and writes the
54// corresponding "<" to b[dst:], returning the incremented dst and src cursors.
55// Precondition: b[src] == '&' && dst <= src.
56// attribute should be true if parsing an attribute value.
57func unescapeEntity(b []byte, dst, src int, attribute bool) (dst1, src1 int) {
58 // https://html.spec.whatwg.org/multipage/syntax.html#consume-a-character-reference
59
60 // i starts at 1 because we already know that s[0] == '&'.
61 i, s := 1, b[src:]
62
63 if len(s) <= 1 {
64 b[dst] = b[src]
65 return dst + 1, src + 1
66 }
67
68 if s[i] == '#' {
69 if len(s) <= 3 { // We need to have at least "&#.".
70 b[dst] = b[src]
71 return dst + 1, src + 1
72 }
73 i++
74 c := s[i]
75 hex := false
76 if c == 'x' || c == 'X' {
77 hex = true
78 i++
79 }
80
81 x := '\x00'
82 for i < len(s) {
83 c = s[i]
84 i++
85 if hex {
86 if '0' <= c && c <= '9' {
87 x = 16*x + rune(c) - '0'
88 continue
89 } else if 'a' <= c && c <= 'f' {
90 x = 16*x + rune(c) - 'a' + 10
91 continue
92 } else if 'A' <= c && c <= 'F' {
93 x = 16*x + rune(c) - 'A' + 10
94 continue
95 }
96 } else if '0' <= c && c <= '9' {
97 x = 10*x + rune(c) - '0'
98 continue
99 }
100 if c != ';' {
101 i--
102 }
103 break
104 }
105
106 if i <= 3 { // No characters matched.
107 b[dst] = b[src]
108 return dst + 1, src + 1
109 }
110
111 if 0x80 <= x && x <= 0x9F {
112 // Replace characters from Windows-1252 with UTF-8 equivalents.
113 x = replacementTable[x-0x80]
114 } else if x == 0 || (0xD800 <= x && x <= 0xDFFF) || x > 0x10FFFF {
115 // Replace invalid characters with the replacement character.
116 x = '\uFFFD'
117 }
118
119 return dst + utf8.EncodeRune(b[dst:], x), src + i
120 }
121
122 // Consume the maximum number of characters possible, with the
123 // consumed characters matching one of the named references.
124
125 for i < len(s) {
126 c := s[i]
127 i++
128 // Lower-cased characters are more common in entities, so we check for them first.
129 if 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || '0' <= c && c <= '9' {
130 continue
131 }
132 if c != ';' {
133 i--
134 }
135 break
136 }
137
138 entityName := string(s[1:i])
139 if entityName == "" {
140 // No-op.
141 } else if attribute && entityName[len(entityName)-1] != ';' && len(s) > i && s[i] == '=' {
142 // No-op.
143 } else if x := entity[entityName]; x != 0 {
144 return dst + utf8.EncodeRune(b[dst:], x), src + i
145 } else if x := entity2[entityName]; x[0] != 0 {
146 dst1 := dst + utf8.EncodeRune(b[dst:], x[0])
147 return dst1 + utf8.EncodeRune(b[dst1:], x[1]), src + i
148 } else if !attribute {
149 maxLen := len(entityName) - 1
150 if maxLen > longestEntityWithoutSemicolon {
151 maxLen = longestEntityWithoutSemicolon
152 }
153 for j := maxLen; j > 1; j-- {
154 if x := entity[entityName[:j]]; x != 0 {
155 return dst + utf8.EncodeRune(b[dst:], x), src + j + 1
156 }
157 }
158 }
159
160 dst1, src1 = dst+i, src+i
161 copy(b[dst:dst1], b[src:src1])
162 return dst1, src1
163}
164
165// unescape unescapes b's entities in-place, so that "a&lt;b" becomes "a<b".
166// attribute should be true if parsing an attribute value.
167func unescape(b []byte, attribute bool) []byte {
168 for i, c := range b {
169 if c == '&' {
170 dst, src := unescapeEntity(b, i, i, attribute)
171 for src < len(b) {
172 c := b[src]
173 if c == '&' {
174 dst, src = unescapeEntity(b, dst, src, attribute)
175 } else {
176 b[dst] = c
177 dst, src = dst+1, src+1
178 }
179 }
180 return b[0:dst]
181 }
182 }
183 return b
184}
185
186// lower lower-cases the A-Z bytes in b in-place, so that "aBc" becomes "abc".
187func lower(b []byte) []byte {
188 for i, c := range b {
189 if 'A' <= c && c <= 'Z' {
190 b[i] = c + 'a' - 'A'
191 }
192 }
193 return b
194}
195
196const escapedChars = "&'<>\"\r"
197
198func escape(w writer, s string) error {
199 i := strings.IndexAny(s, escapedChars)
200 for i != -1 {
201 if _, err := w.WriteString(s[:i]); err != nil {
202 return err
203 }
204 var esc string
205 switch s[i] {
206 case '&':
207 esc = "&amp;"
208 case '\'':
209 // "&#39;" is shorter than "&apos;" and apos was not in HTML until HTML5.
210 esc = "&#39;"
211 case '<':
212 esc = "&lt;"
213 case '>':
214 esc = "&gt;"
215 case '"':
216 // "&#34;" is shorter than "&quot;".
217 esc = "&#34;"
218 case '\r':
219 esc = "&#13;"
220 default:
221 panic("unrecognized escape character")
222 }
223 s = s[i+1:]
224 if _, err := w.WriteString(esc); err != nil {
225 return err
226 }
227 i = strings.IndexAny(s, escapedChars)
228 }
229 _, err := w.WriteString(s)
230 return err
231}
232
233// EscapeString escapes special characters like "<" to become "&lt;". It
234// escapes only five such characters: <, >, &, ' and ".
235// UnescapeString(EscapeString(s)) == s always holds, but the converse isn't
236// always true.
237func EscapeString(s string) string {
238 if strings.IndexAny(s, escapedChars) == -1 {
239 return s
240 }
241 var buf bytes.Buffer
242 escape(&buf, s)
243 return buf.String()
244}
245
246// UnescapeString unescapes entities like "&lt;" to become "<". It unescapes a
247// larger range of entities than EscapeString escapes. For example, "&aacute;"
248// unescapes to "á", as does "&#225;" and "&xE1;".
249// UnescapeString(EscapeString(s)) == s always holds, but the converse isn't
250// always true.
251func UnescapeString(s string) string {
252 for _, c := range s {
253 if c == '&' {
254 return string(unescape([]byte(s), false))
255 }
256 }
257 return s
258}
diff --git a/vendor/golang.org/x/net/html/foreign.go b/vendor/golang.org/x/net/html/foreign.go
new file mode 100644
index 0000000..d3b3844
--- /dev/null
+++ b/vendor/golang.org/x/net/html/foreign.go
@@ -0,0 +1,226 @@
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
5package html
6
7import (
8 "strings"
9)
10
11func adjustAttributeNames(aa []Attribute, nameMap map[string]string) {
12 for i := range aa {
13 if newName, ok := nameMap[aa[i].Key]; ok {
14 aa[i].Key = newName
15 }
16 }
17}
18
19func adjustForeignAttributes(aa []Attribute) {
20 for i, a := range aa {
21 if a.Key == "" || a.Key[0] != 'x' {
22 continue
23 }
24 switch a.Key {
25 case "xlink:actuate", "xlink:arcrole", "xlink:href", "xlink:role", "xlink:show",
26 "xlink:title", "xlink:type", "xml:base", "xml:lang", "xml:space", "xmlns:xlink":
27 j := strings.Index(a.Key, ":")
28 aa[i].Namespace = a.Key[:j]
29 aa[i].Key = a.Key[j+1:]
30 }
31 }
32}
33
34func htmlIntegrationPoint(n *Node) bool {
35 if n.Type != ElementNode {
36 return false
37 }
38 switch n.Namespace {
39 case "math":
40 if n.Data == "annotation-xml" {
41 for _, a := range n.Attr {
42 if a.Key == "encoding" {
43 val := strings.ToLower(a.Val)
44 if val == "text/html" || val == "application/xhtml+xml" {
45 return true
46 }
47 }
48 }
49 }
50 case "svg":
51 switch n.Data {
52 case "desc", "foreignObject", "title":
53 return true
54 }
55 }
56 return false
57}
58
59func mathMLTextIntegrationPoint(n *Node) bool {
60 if n.Namespace != "math" {
61 return false
62 }
63 switch n.Data {
64 case "mi", "mo", "mn", "ms", "mtext":
65 return true
66 }
67 return false
68}
69
70// Section 12.2.5.5.
71var breakout = map[string]bool{
72 "b": true,
73 "big": true,
74 "blockquote": true,
75 "body": true,
76 "br": true,
77 "center": true,
78 "code": true,
79 "dd": true,
80 "div": true,
81 "dl": true,
82 "dt": true,
83 "em": true,
84 "embed": true,
85 "h1": true,
86 "h2": true,
87 "h3": true,
88 "h4": true,
89 "h5": true,
90 "h6": true,
91 "head": true,
92 "hr": true,
93 "i": true,
94 "img": true,
95 "li": true,
96 "listing": true,
97 "menu": true,
98 "meta": true,
99 "nobr": true,
100 "ol": true,
101 "p": true,
102 "pre": true,
103 "ruby": true,
104 "s": true,
105 "small": true,
106 "span": true,
107 "strong": true,
108 "strike": true,
109 "sub": true,
110 "sup": true,
111 "table": true,
112 "tt": true,
113 "u": true,
114 "ul": true,
115 "var": true,
116}
117
118// Section 12.2.5.5.
119var svgTagNameAdjustments = map[string]string{
120 "altglyph": "altGlyph",
121 "altglyphdef": "altGlyphDef",
122 "altglyphitem": "altGlyphItem",
123 "animatecolor": "animateColor",
124 "animatemotion": "animateMotion",
125 "animatetransform": "animateTransform",
126 "clippath": "clipPath",
127 "feblend": "feBlend",
128 "fecolormatrix": "feColorMatrix",
129 "fecomponenttransfer": "feComponentTransfer",
130 "fecomposite": "feComposite",
131 "feconvolvematrix": "feConvolveMatrix",
132 "fediffuselighting": "feDiffuseLighting",
133 "fedisplacementmap": "feDisplacementMap",
134 "fedistantlight": "feDistantLight",
135 "feflood": "feFlood",
136 "fefunca": "feFuncA",
137 "fefuncb": "feFuncB",
138 "fefuncg": "feFuncG",
139 "fefuncr": "feFuncR",
140 "fegaussianblur": "feGaussianBlur",
141 "feimage": "feImage",
142 "femerge": "feMerge",
143 "femergenode": "feMergeNode",
144 "femorphology": "feMorphology",
145 "feoffset": "feOffset",
146 "fepointlight": "fePointLight",
147 "fespecularlighting": "feSpecularLighting",
148 "fespotlight": "feSpotLight",
149 "fetile": "feTile",
150 "feturbulence": "feTurbulence",
151 "foreignobject": "foreignObject",
152 "glyphref": "glyphRef",
153 "lineargradient": "linearGradient",
154 "radialgradient": "radialGradient",
155 "textpath": "textPath",
156}
157
158// Section 12.2.5.1
159var mathMLAttributeAdjustments = map[string]string{
160 "definitionurl": "definitionURL",
161}
162
163var svgAttributeAdjustments = map[string]string{
164 "attributename": "attributeName",
165 "attributetype": "attributeType",
166 "basefrequency": "baseFrequency",
167 "baseprofile": "baseProfile",
168 "calcmode": "calcMode",
169 "clippathunits": "clipPathUnits",
170 "contentscripttype": "contentScriptType",
171 "contentstyletype": "contentStyleType",
172 "diffuseconstant": "diffuseConstant",
173 "edgemode": "edgeMode",
174 "externalresourcesrequired": "externalResourcesRequired",
175 "filterres": "filterRes",
176 "filterunits": "filterUnits",
177 "glyphref": "glyphRef",
178 "gradienttransform": "gradientTransform",
179 "gradientunits": "gradientUnits",
180 "kernelmatrix": "kernelMatrix",
181 "kernelunitlength": "kernelUnitLength",
182 "keypoints": "keyPoints",
183 "keysplines": "keySplines",
184 "keytimes": "keyTimes",
185 "lengthadjust": "lengthAdjust",
186 "limitingconeangle": "limitingConeAngle",
187 "markerheight": "markerHeight",
188 "markerunits": "markerUnits",
189 "markerwidth": "markerWidth",
190 "maskcontentunits": "maskContentUnits",
191 "maskunits": "maskUnits",
192 "numoctaves": "numOctaves",
193 "pathlength": "pathLength",
194 "patterncontentunits": "patternContentUnits",
195 "patterntransform": "patternTransform",
196 "patternunits": "patternUnits",
197 "pointsatx": "pointsAtX",
198 "pointsaty": "pointsAtY",
199 "pointsatz": "pointsAtZ",
200 "preservealpha": "preserveAlpha",
201 "preserveaspectratio": "preserveAspectRatio",
202 "primitiveunits": "primitiveUnits",
203 "refx": "refX",
204 "refy": "refY",
205 "repeatcount": "repeatCount",
206 "repeatdur": "repeatDur",
207 "requiredextensions": "requiredExtensions",
208 "requiredfeatures": "requiredFeatures",
209 "specularconstant": "specularConstant",
210 "specularexponent": "specularExponent",
211 "spreadmethod": "spreadMethod",
212 "startoffset": "startOffset",
213 "stddeviation": "stdDeviation",
214 "stitchtiles": "stitchTiles",
215 "surfacescale": "surfaceScale",
216 "systemlanguage": "systemLanguage",
217 "tablevalues": "tableValues",
218 "targetx": "targetX",
219 "targety": "targetY",
220 "textlength": "textLength",
221 "viewbox": "viewBox",
222 "viewtarget": "viewTarget",
223 "xchannelselector": "xChannelSelector",
224 "ychannelselector": "yChannelSelector",
225 "zoomandpan": "zoomAndPan",
226}
diff --git a/vendor/golang.org/x/net/html/node.go b/vendor/golang.org/x/net/html/node.go
new file mode 100644
index 0000000..26b657a
--- /dev/null
+++ b/vendor/golang.org/x/net/html/node.go
@@ -0,0 +1,193 @@
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
5package html
6
7import (
8 "golang.org/x/net/html/atom"
9)
10
11// A NodeType is the type of a Node.
12type NodeType uint32
13
14const (
15 ErrorNode NodeType = iota
16 TextNode
17 DocumentNode
18 ElementNode
19 CommentNode
20 DoctypeNode
21 scopeMarkerNode
22)
23
24// Section 12.2.3.3 says "scope markers are inserted when entering applet
25// elements, buttons, object elements, marquees, table cells, and table
26// captions, and are used to prevent formatting from 'leaking'".
27var scopeMarker = Node{Type: scopeMarkerNode}
28
29// A Node consists of a NodeType and some Data (tag name for element nodes,
30// content for text) and are part of a tree of Nodes. Element nodes may also
31// have a Namespace and contain a slice of Attributes. Data is unescaped, so
32// that it looks like "a<b" rather than "a&lt;b". For element nodes, DataAtom
33// is the atom for Data, or zero if Data is not a known tag name.
34//
35// An empty Namespace implies a "http://www.w3.org/1999/xhtml" namespace.
36// Similarly, "math" is short for "http://www.w3.org/1998/Math/MathML", and
37// "svg" is short for "http://www.w3.org/2000/svg".
38type Node struct {
39 Parent, FirstChild, LastChild, PrevSibling, NextSibling *Node
40
41 Type NodeType
42 DataAtom atom.Atom
43 Data string
44 Namespace string
45 Attr []Attribute
46}
47
48// InsertBefore inserts newChild as a child of n, immediately before oldChild
49// in the sequence of n's children. oldChild may be nil, in which case newChild
50// is appended to the end of n's children.
51//
52// It will panic if newChild already has a parent or siblings.
53func (n *Node) InsertBefore(newChild, oldChild *Node) {
54 if newChild.Parent != nil || newChild.PrevSibling != nil || newChild.NextSibling != nil {
55 panic("html: InsertBefore called for an attached child Node")
56 }
57 var prev, next *Node
58 if oldChild != nil {
59 prev, next = oldChild.PrevSibling, oldChild
60 } else {
61 prev = n.LastChild
62 }
63 if prev != nil {
64 prev.NextSibling = newChild
65 } else {
66 n.FirstChild = newChild
67 }
68 if next != nil {
69 next.PrevSibling = newChild
70 } else {
71 n.LastChild = newChild
72 }
73 newChild.Parent = n
74 newChild.PrevSibling = prev
75 newChild.NextSibling = next
76}
77
78// AppendChild adds a node c as a child of n.
79//
80// It will panic if c already has a parent or siblings.
81func (n *Node) AppendChild(c *Node) {
82 if c.Parent != nil || c.PrevSibling != nil || c.NextSibling != nil {
83 panic("html: AppendChild called for an attached child Node")
84 }
85 last := n.LastChild
86 if last != nil {
87 last.NextSibling = c
88 } else {
89 n.FirstChild = c
90 }
91 n.LastChild = c
92 c.Parent = n
93 c.PrevSibling = last
94}
95
96// RemoveChild removes a node c that is a child of n. Afterwards, c will have
97// no parent and no siblings.
98//
99// It will panic if c's parent is not n.
100func (n *Node) RemoveChild(c *Node) {
101 if c.Parent != n {
102 panic("html: RemoveChild called for a non-child Node")
103 }
104 if n.FirstChild == c {
105 n.FirstChild = c.NextSibling
106 }
107 if c.NextSibling != nil {
108 c.NextSibling.PrevSibling = c.PrevSibling
109 }
110 if n.LastChild == c {
111 n.LastChild = c.PrevSibling
112 }
113 if c.PrevSibling != nil {
114 c.PrevSibling.NextSibling = c.NextSibling
115 }
116 c.Parent = nil
117 c.PrevSibling = nil
118 c.NextSibling = nil
119}
120
121// reparentChildren reparents all of src's child nodes to dst.
122func reparentChildren(dst, src *Node) {
123 for {
124 child := src.FirstChild
125 if child == nil {
126 break
127 }
128 src.RemoveChild(child)
129 dst.AppendChild(child)
130 }
131}
132
133// clone returns a new node with the same type, data and attributes.
134// The clone has no parent, no siblings and no children.
135func (n *Node) clone() *Node {
136 m := &Node{
137 Type: n.Type,
138 DataAtom: n.DataAtom,
139 Data: n.Data,
140 Attr: make([]Attribute, len(n.Attr)),
141 }
142 copy(m.Attr, n.Attr)
143 return m
144}
145
146// nodeStack is a stack of nodes.
147type nodeStack []*Node
148
149// pop pops the stack. It will panic if s is empty.
150func (s *nodeStack) pop() *Node {
151 i := len(*s)
152 n := (*s)[i-1]
153 *s = (*s)[:i-1]
154 return n
155}
156
157// top returns the most recently pushed node, or nil if s is empty.
158func (s *nodeStack) top() *Node {
159 if i := len(*s); i > 0 {
160 return (*s)[i-1]
161 }
162 return nil
163}
164
165// index returns the index of the top-most occurrence of n in the stack, or -1
166// if n is not present.
167func (s *nodeStack) index(n *Node) int {
168 for i := len(*s) - 1; i >= 0; i-- {
169 if (*s)[i] == n {
170 return i
171 }
172 }
173 return -1
174}
175
176// insert inserts a node at the given index.
177func (s *nodeStack) insert(i int, n *Node) {
178 (*s) = append(*s, nil)
179 copy((*s)[i+1:], (*s)[i:])
180 (*s)[i] = n
181}
182
183// remove removes a node from the stack. It is a no-op if n is not present.
184func (s *nodeStack) remove(n *Node) {
185 i := s.index(n)
186 if i == -1 {
187 return
188 }
189 copy((*s)[i:], (*s)[i+1:])
190 j := len(*s) - 1
191 (*s)[j] = nil
192 *s = (*s)[:j]
193}
diff --git a/vendor/golang.org/x/net/html/parse.go b/vendor/golang.org/x/net/html/parse.go
new file mode 100644
index 0000000..be4b2bf
--- /dev/null
+++ b/vendor/golang.org/x/net/html/parse.go
@@ -0,0 +1,2094 @@
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
5package html
6
7import (
8 "errors"
9 "fmt"
10 "io"
11 "strings"
12
13 a "golang.org/x/net/html/atom"
14)
15
16// A parser implements the HTML5 parsing algorithm:
17// https://html.spec.whatwg.org/multipage/syntax.html#tree-construction
18type parser struct {
19 // tokenizer provides the tokens for the parser.
20 tokenizer *Tokenizer
21 // tok is the most recently read token.
22 tok Token
23 // Self-closing tags like <hr/> are treated as start tags, except that
24 // hasSelfClosingToken is set while they are being processed.
25 hasSelfClosingToken bool
26 // doc is the document root element.
27 doc *Node
28 // The stack of open elements (section 12.2.3.2) and active formatting
29 // elements (section 12.2.3.3).
30 oe, afe nodeStack
31 // Element pointers (section 12.2.3.4).
32 head, form *Node
33 // Other parsing state flags (section 12.2.3.5).
34 scripting, framesetOK bool
35 // im is the current insertion mode.
36 im insertionMode
37 // originalIM is the insertion mode to go back to after completing a text
38 // or inTableText insertion mode.
39 originalIM insertionMode
40 // fosterParenting is whether new elements should be inserted according to
41 // the foster parenting rules (section 12.2.5.3).
42 fosterParenting bool
43 // quirks is whether the parser is operating in "quirks mode."
44 quirks bool
45 // fragment is whether the parser is parsing an HTML fragment.
46 fragment bool
47 // context is the context element when parsing an HTML fragment
48 // (section 12.4).
49 context *Node
50}
51
52func (p *parser) top() *Node {
53 if n := p.oe.top(); n != nil {
54 return n
55 }
56 return p.doc
57}
58
59// Stop tags for use in popUntil. These come from section 12.2.3.2.
60var (
61 defaultScopeStopTags = map[string][]a.Atom{
62 "": {a.Applet, a.Caption, a.Html, a.Table, a.Td, a.Th, a.Marquee, a.Object, a.Template},
63 "math": {a.AnnotationXml, a.Mi, a.Mn, a.Mo, a.Ms, a.Mtext},
64 "svg": {a.Desc, a.ForeignObject, a.Title},
65 }
66)
67
68type scope int
69
70const (
71 defaultScope scope = iota
72 listItemScope
73 buttonScope
74 tableScope
75 tableRowScope
76 tableBodyScope
77 selectScope
78)
79
80// popUntil pops the stack of open elements at the highest element whose tag
81// is in matchTags, provided there is no higher element in the scope's stop
82// tags (as defined in section 12.2.3.2). It returns whether or not there was
83// such an element. If there was not, popUntil leaves the stack unchanged.
84//
85// For example, the set of stop tags for table scope is: "html", "table". If
86// the stack was:
87// ["html", "body", "font", "table", "b", "i", "u"]
88// then popUntil(tableScope, "font") would return false, but
89// popUntil(tableScope, "i") would return true and the stack would become:
90// ["html", "body", "font", "table", "b"]
91//
92// If an element's tag is in both the stop tags and matchTags, then the stack
93// will be popped and the function returns true (provided, of course, there was
94// no higher element in the stack that was also in the stop tags). For example,
95// popUntil(tableScope, "table") returns true and leaves:
96// ["html", "body", "font"]
97func (p *parser) popUntil(s scope, matchTags ...a.Atom) bool {
98 if i := p.indexOfElementInScope(s, matchTags...); i != -1 {
99 p.oe = p.oe[:i]
100 return true
101 }
102 return false
103}
104
105// indexOfElementInScope returns the index in p.oe of the highest element whose
106// tag is in matchTags that is in scope. If no matching element is in scope, it
107// returns -1.
108func (p *parser) indexOfElementInScope(s scope, matchTags ...a.Atom) int {
109 for i := len(p.oe) - 1; i >= 0; i-- {
110 tagAtom := p.oe[i].DataAtom
111 if p.oe[i].Namespace == "" {
112 for _, t := range matchTags {
113 if t == tagAtom {
114 return i
115 }
116 }
117 switch s {
118 case defaultScope:
119 // No-op.
120 case listItemScope:
121 if tagAtom == a.Ol || tagAtom == a.Ul {
122 return -1
123 }
124 case buttonScope:
125 if tagAtom == a.Button {
126 return -1
127 }
128 case tableScope:
129 if tagAtom == a.Html || tagAtom == a.Table {
130 return -1
131 }
132 case selectScope:
133 if tagAtom != a.Optgroup && tagAtom != a.Option {
134 return -1
135 }
136 default:
137 panic("unreachable")
138 }
139 }
140 switch s {
141 case defaultScope, listItemScope, buttonScope:
142 for _, t := range defaultScopeStopTags[p.oe[i].Namespace] {
143 if t == tagAtom {
144 return -1
145 }
146 }
147 }
148 }
149 return -1
150}
151
152// elementInScope is like popUntil, except that it doesn't modify the stack of
153// open elements.
154func (p *parser) elementInScope(s scope, matchTags ...a.Atom) bool {
155 return p.indexOfElementInScope(s, matchTags...) != -1
156}
157
158// clearStackToContext pops elements off the stack of open elements until a
159// scope-defined element is found.
160func (p *parser) clearStackToContext(s scope) {
161 for i := len(p.oe) - 1; i >= 0; i-- {
162 tagAtom := p.oe[i].DataAtom
163 switch s {
164 case tableScope:
165 if tagAtom == a.Html || tagAtom == a.Table {
166 p.oe = p.oe[:i+1]
167 return
168 }
169 case tableRowScope:
170 if tagAtom == a.Html || tagAtom == a.Tr {
171 p.oe = p.oe[:i+1]
172 return
173 }
174 case tableBodyScope:
175 if tagAtom == a.Html || tagAtom == a.Tbody || tagAtom == a.Tfoot || tagAtom == a.Thead {
176 p.oe = p.oe[:i+1]
177 return
178 }
179 default:
180 panic("unreachable")
181 }
182 }
183}
184
185// generateImpliedEndTags pops nodes off the stack of open elements as long as
186// the top node has a tag name of dd, dt, li, option, optgroup, p, rp, or rt.
187// If exceptions are specified, nodes with that name will not be popped off.
188func (p *parser) generateImpliedEndTags(exceptions ...string) {
189 var i int
190loop:
191 for i = len(p.oe) - 1; i >= 0; i-- {
192 n := p.oe[i]
193 if n.Type == ElementNode {
194 switch n.DataAtom {
195 case a.Dd, a.Dt, a.Li, a.Option, a.Optgroup, a.P, a.Rp, a.Rt:
196 for _, except := range exceptions {
197 if n.Data == except {
198 break loop
199 }
200 }
201 continue
202 }
203 }
204 break
205 }
206
207 p.oe = p.oe[:i+1]
208}
209
210// addChild adds a child node n to the top element, and pushes n onto the stack
211// of open elements if it is an element node.
212func (p *parser) addChild(n *Node) {
213 if p.shouldFosterParent() {
214 p.fosterParent(n)
215 } else {
216 p.top().AppendChild(n)
217 }
218
219 if n.Type == ElementNode {
220 p.oe = append(p.oe, n)
221 }
222}
223
224// shouldFosterParent returns whether the next node to be added should be
225// foster parented.
226func (p *parser) shouldFosterParent() bool {
227 if p.fosterParenting {
228 switch p.top().DataAtom {
229 case a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr:
230 return true
231 }
232 }
233 return false
234}
235
236// fosterParent adds a child node according to the foster parenting rules.
237// Section 12.2.5.3, "foster parenting".
238func (p *parser) fosterParent(n *Node) {
239 var table, parent, prev *Node
240 var i int
241 for i = len(p.oe) - 1; i >= 0; i-- {
242 if p.oe[i].DataAtom == a.Table {
243 table = p.oe[i]
244 break
245 }
246 }
247
248 if table == nil {
249 // The foster parent is the html element.
250 parent = p.oe[0]
251 } else {
252 parent = table.Parent
253 }
254 if parent == nil {
255 parent = p.oe[i-1]
256 }
257
258 if table != nil {
259 prev = table.PrevSibling
260 } else {
261 prev = parent.LastChild
262 }
263 if prev != nil && prev.Type == TextNode && n.Type == TextNode {
264 prev.Data += n.Data
265 return
266 }
267
268 parent.InsertBefore(n, table)
269}
270
271// addText adds text to the preceding node if it is a text node, or else it
272// calls addChild with a new text node.
273func (p *parser) addText(text string) {
274 if text == "" {
275 return
276 }
277
278 if p.shouldFosterParent() {
279 p.fosterParent(&Node{
280 Type: TextNode,
281 Data: text,
282 })
283 return
284 }
285
286 t := p.top()
287 if n := t.LastChild; n != nil && n.Type == TextNode {
288 n.Data += text
289 return
290 }
291 p.addChild(&Node{
292 Type: TextNode,
293 Data: text,
294 })
295}
296
297// addElement adds a child element based on the current token.
298func (p *parser) addElement() {
299 p.addChild(&Node{
300 Type: ElementNode,
301 DataAtom: p.tok.DataAtom,
302 Data: p.tok.Data,
303 Attr: p.tok.Attr,
304 })
305}
306
307// Section 12.2.3.3.
308func (p *parser) addFormattingElement() {
309 tagAtom, attr := p.tok.DataAtom, p.tok.Attr
310 p.addElement()
311
312 // Implement the Noah's Ark clause, but with three per family instead of two.
313 identicalElements := 0
314findIdenticalElements:
315 for i := len(p.afe) - 1; i >= 0; i-- {
316 n := p.afe[i]
317 if n.Type == scopeMarkerNode {
318 break
319 }
320 if n.Type != ElementNode {
321 continue
322 }
323 if n.Namespace != "" {
324 continue
325 }
326 if n.DataAtom != tagAtom {
327 continue
328 }
329 if len(n.Attr) != len(attr) {
330 continue
331 }
332 compareAttributes:
333 for _, t0 := range n.Attr {
334 for _, t1 := range attr {
335 if t0.Key == t1.Key && t0.Namespace == t1.Namespace && t0.Val == t1.Val {
336 // Found a match for this attribute, continue with the next attribute.
337 continue compareAttributes
338 }
339 }
340 // If we get here, there is no attribute that matches a.
341 // Therefore the element is not identical to the new one.
342 continue findIdenticalElements
343 }
344
345 identicalElements++
346 if identicalElements >= 3 {
347 p.afe.remove(n)
348 }
349 }
350
351 p.afe = append(p.afe, p.top())
352}
353
354// Section 12.2.3.3.
355func (p *parser) clearActiveFormattingElements() {
356 for {
357 n := p.afe.pop()
358 if len(p.afe) == 0 || n.Type == scopeMarkerNode {
359 return
360 }
361 }
362}
363
364// Section 12.2.3.3.
365func (p *parser) reconstructActiveFormattingElements() {
366 n := p.afe.top()
367 if n == nil {
368 return
369 }
370 if n.Type == scopeMarkerNode || p.oe.index(n) != -1 {
371 return
372 }
373 i := len(p.afe) - 1
374 for n.Type != scopeMarkerNode && p.oe.index(n) == -1 {
375 if i == 0 {
376 i = -1
377 break
378 }
379 i--
380 n = p.afe[i]
381 }
382 for {
383 i++
384 clone := p.afe[i].clone()
385 p.addChild(clone)
386 p.afe[i] = clone
387 if i == len(p.afe)-1 {
388 break
389 }
390 }
391}
392
393// Section 12.2.4.
394func (p *parser) acknowledgeSelfClosingTag() {
395 p.hasSelfClosingToken = false
396}
397
398// An insertion mode (section 12.2.3.1) is the state transition function from
399// a particular state in the HTML5 parser's state machine. It updates the
400// parser's fields depending on parser.tok (where ErrorToken means EOF).
401// It returns whether the token was consumed.
402type insertionMode func(*parser) bool
403
404// setOriginalIM sets the insertion mode to return to after completing a text or
405// inTableText insertion mode.
406// Section 12.2.3.1, "using the rules for".
407func (p *parser) setOriginalIM() {
408 if p.originalIM != nil {
409 panic("html: bad parser state: originalIM was set twice")
410 }
411 p.originalIM = p.im
412}
413
414// Section 12.2.3.1, "reset the insertion mode".
415func (p *parser) resetInsertionMode() {
416 for i := len(p.oe) - 1; i >= 0; i-- {
417 n := p.oe[i]
418 if i == 0 && p.context != nil {
419 n = p.context
420 }
421
422 switch n.DataAtom {
423 case a.Select:
424 p.im = inSelectIM
425 case a.Td, a.Th:
426 p.im = inCellIM
427 case a.Tr:
428 p.im = inRowIM
429 case a.Tbody, a.Thead, a.Tfoot:
430 p.im = inTableBodyIM
431 case a.Caption:
432 p.im = inCaptionIM
433 case a.Colgroup:
434 p.im = inColumnGroupIM
435 case a.Table:
436 p.im = inTableIM
437 case a.Head:
438 p.im = inBodyIM
439 case a.Body:
440 p.im = inBodyIM
441 case a.Frameset:
442 p.im = inFramesetIM
443 case a.Html:
444 p.im = beforeHeadIM
445 default:
446 continue
447 }
448 return
449 }
450 p.im = inBodyIM
451}
452
453const whitespace = " \t\r\n\f"
454
455// Section 12.2.5.4.1.
456func initialIM(p *parser) bool {
457 switch p.tok.Type {
458 case TextToken:
459 p.tok.Data = strings.TrimLeft(p.tok.Data, whitespace)
460 if len(p.tok.Data) == 0 {
461 // It was all whitespace, so ignore it.
462 return true
463 }
464 case CommentToken:
465 p.doc.AppendChild(&Node{
466 Type: CommentNode,
467 Data: p.tok.Data,
468 })
469 return true
470 case DoctypeToken:
471 n, quirks := parseDoctype(p.tok.Data)
472 p.doc.AppendChild(n)
473 p.quirks = quirks
474 p.im = beforeHTMLIM
475 return true
476 }
477 p.quirks = true
478 p.im = beforeHTMLIM
479 return false
480}
481
482// Section 12.2.5.4.2.
483func beforeHTMLIM(p *parser) bool {
484 switch p.tok.Type {
485 case DoctypeToken:
486 // Ignore the token.
487 return true
488 case TextToken:
489 p.tok.Data = strings.TrimLeft(p.tok.Data, whitespace)
490 if len(p.tok.Data) == 0 {
491 // It was all whitespace, so ignore it.
492 return true
493 }
494 case StartTagToken:
495 if p.tok.DataAtom == a.Html {
496 p.addElement()
497 p.im = beforeHeadIM
498 return true
499 }
500 case EndTagToken:
501 switch p.tok.DataAtom {
502 case a.Head, a.Body, a.Html, a.Br:
503 p.parseImpliedToken(StartTagToken, a.Html, a.Html.String())
504 return false
505 default:
506 // Ignore the token.
507 return true
508 }
509 case CommentToken:
510 p.doc.AppendChild(&Node{
511 Type: CommentNode,
512 Data: p.tok.Data,
513 })
514 return true
515 }
516 p.parseImpliedToken(StartTagToken, a.Html, a.Html.String())
517 return false
518}
519
520// Section 12.2.5.4.3.
521func beforeHeadIM(p *parser) bool {
522 switch p.tok.Type {
523 case TextToken:
524 p.tok.Data = strings.TrimLeft(p.tok.Data, whitespace)
525 if len(p.tok.Data) == 0 {
526 // It was all whitespace, so ignore it.
527 return true
528 }
529 case StartTagToken:
530 switch p.tok.DataAtom {
531 case a.Head:
532 p.addElement()
533 p.head = p.top()
534 p.im = inHeadIM
535 return true
536 case a.Html:
537 return inBodyIM(p)
538 }
539 case EndTagToken:
540 switch p.tok.DataAtom {
541 case a.Head, a.Body, a.Html, a.Br:
542 p.parseImpliedToken(StartTagToken, a.Head, a.Head.String())
543 return false
544 default:
545 // Ignore the token.
546 return true
547 }
548 case CommentToken:
549 p.addChild(&Node{
550 Type: CommentNode,
551 Data: p.tok.Data,
552 })
553 return true
554 case DoctypeToken:
555 // Ignore the token.
556 return true
557 }
558
559 p.parseImpliedToken(StartTagToken, a.Head, a.Head.String())
560 return false
561}
562
563// Section 12.2.5.4.4.
564func inHeadIM(p *parser) bool {
565 switch p.tok.Type {
566 case TextToken:
567 s := strings.TrimLeft(p.tok.Data, whitespace)
568 if len(s) < len(p.tok.Data) {
569 // Add the initial whitespace to the current node.
570 p.addText(p.tok.Data[:len(p.tok.Data)-len(s)])
571 if s == "" {
572 return true
573 }
574 p.tok.Data = s
575 }
576 case StartTagToken:
577 switch p.tok.DataAtom {
578 case a.Html:
579 return inBodyIM(p)
580 case a.Base, a.Basefont, a.Bgsound, a.Command, a.Link, a.Meta:
581 p.addElement()
582 p.oe.pop()
583 p.acknowledgeSelfClosingTag()
584 return true
585 case a.Script, a.Title, a.Noscript, a.Noframes, a.Style:
586 p.addElement()
587 p.setOriginalIM()
588 p.im = textIM
589 return true
590 case a.Head:
591 // Ignore the token.
592 return true
593 }
594 case EndTagToken:
595 switch p.tok.DataAtom {
596 case a.Head:
597 n := p.oe.pop()
598 if n.DataAtom != a.Head {
599 panic("html: bad parser state: <head> element not found, in the in-head insertion mode")
600 }
601 p.im = afterHeadIM
602 return true
603 case a.Body, a.Html, a.Br:
604 p.parseImpliedToken(EndTagToken, a.Head, a.Head.String())
605 return false
606 default:
607 // Ignore the token.
608 return true
609 }
610 case CommentToken:
611 p.addChild(&Node{
612 Type: CommentNode,
613 Data: p.tok.Data,
614 })
615 return true
616 case DoctypeToken:
617 // Ignore the token.
618 return true
619 }
620
621 p.parseImpliedToken(EndTagToken, a.Head, a.Head.String())
622 return false
623}
624
625// Section 12.2.5.4.6.
626func afterHeadIM(p *parser) bool {
627 switch p.tok.Type {
628 case TextToken:
629 s := strings.TrimLeft(p.tok.Data, whitespace)
630 if len(s) < len(p.tok.Data) {
631 // Add the initial whitespace to the current node.
632 p.addText(p.tok.Data[:len(p.tok.Data)-len(s)])
633 if s == "" {
634 return true
635 }
636 p.tok.Data = s
637 }
638 case StartTagToken:
639 switch p.tok.DataAtom {
640 case a.Html:
641 return inBodyIM(p)
642 case a.Body:
643 p.addElement()
644 p.framesetOK = false
645 p.im = inBodyIM
646 return true
647 case a.Frameset:
648 p.addElement()
649 p.im = inFramesetIM
650 return true
651 case a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Title:
652 p.oe = append(p.oe, p.head)
653 defer p.oe.remove(p.head)
654 return inHeadIM(p)
655 case a.Head:
656 // Ignore the token.
657 return true
658 }
659 case EndTagToken:
660 switch p.tok.DataAtom {
661 case a.Body, a.Html, a.Br:
662 // Drop down to creating an implied <body> tag.
663 default:
664 // Ignore the token.
665 return true
666 }
667 case CommentToken:
668 p.addChild(&Node{
669 Type: CommentNode,
670 Data: p.tok.Data,
671 })
672 return true
673 case DoctypeToken:
674 // Ignore the token.
675 return true
676 }
677
678 p.parseImpliedToken(StartTagToken, a.Body, a.Body.String())
679 p.framesetOK = true
680 return false
681}
682
683// copyAttributes copies attributes of src not found on dst to dst.
684func copyAttributes(dst *Node, src Token) {
685 if len(src.Attr) == 0 {
686 return
687 }
688 attr := map[string]string{}
689 for _, t := range dst.Attr {
690 attr[t.Key] = t.Val
691 }
692 for _, t := range src.Attr {
693 if _, ok := attr[t.Key]; !ok {
694 dst.Attr = append(dst.Attr, t)
695 attr[t.Key] = t.Val
696 }
697 }
698}
699
700// Section 12.2.5.4.7.
701func inBodyIM(p *parser) bool {
702 switch p.tok.Type {
703 case TextToken:
704 d := p.tok.Data
705 switch n := p.oe.top(); n.DataAtom {
706 case a.Pre, a.Listing:
707 if n.FirstChild == nil {
708 // Ignore a newline at the start of a <pre> block.
709 if d != "" && d[0] == '\r' {
710 d = d[1:]
711 }
712 if d != "" && d[0] == '\n' {
713 d = d[1:]
714 }
715 }
716 }
717 d = strings.Replace(d, "\x00", "", -1)
718 if d == "" {
719 return true
720 }
721 p.reconstructActiveFormattingElements()
722 p.addText(d)
723 if p.framesetOK && strings.TrimLeft(d, whitespace) != "" {
724 // There were non-whitespace characters inserted.
725 p.framesetOK = false
726 }
727 case StartTagToken:
728 switch p.tok.DataAtom {
729 case a.Html:
730 copyAttributes(p.oe[0], p.tok)
731 case a.Base, a.Basefont, a.Bgsound, a.Command, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Title:
732 return inHeadIM(p)
733 case a.Body:
734 if len(p.oe) >= 2 {
735 body := p.oe[1]
736 if body.Type == ElementNode && body.DataAtom == a.Body {
737 p.framesetOK = false
738 copyAttributes(body, p.tok)
739 }
740 }
741 case a.Frameset:
742 if !p.framesetOK || len(p.oe) < 2 || p.oe[1].DataAtom != a.Body {
743 // Ignore the token.
744 return true
745 }
746 body := p.oe[1]
747 if body.Parent != nil {
748 body.Parent.RemoveChild(body)
749 }
750 p.oe = p.oe[:1]
751 p.addElement()
752 p.im = inFramesetIM
753 return true
754 case a.Address, a.Article, a.Aside, a.Blockquote, a.Center, a.Details, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Menu, a.Nav, a.Ol, a.P, a.Section, a.Summary, a.Ul:
755 p.popUntil(buttonScope, a.P)
756 p.addElement()
757 case a.H1, a.H2, a.H3, a.H4, a.H5, a.H6:
758 p.popUntil(buttonScope, a.P)
759 switch n := p.top(); n.DataAtom {
760 case a.H1, a.H2, a.H3, a.H4, a.H5, a.H6:
761 p.oe.pop()
762 }
763 p.addElement()
764 case a.Pre, a.Listing:
765 p.popUntil(buttonScope, a.P)
766 p.addElement()
767 // The newline, if any, will be dealt with by the TextToken case.
768 p.framesetOK = false
769 case a.Form:
770 if p.form == nil {
771 p.popUntil(buttonScope, a.P)
772 p.addElement()
773 p.form = p.top()
774 }
775 case a.Li:
776 p.framesetOK = false
777 for i := len(p.oe) - 1; i >= 0; i-- {
778 node := p.oe[i]
779 switch node.DataAtom {
780 case a.Li:
781 p.oe = p.oe[:i]
782 case a.Address, a.Div, a.P:
783 continue
784 default:
785 if !isSpecialElement(node) {
786 continue
787 }
788 }
789 break
790 }
791 p.popUntil(buttonScope, a.P)
792 p.addElement()
793 case a.Dd, a.Dt:
794 p.framesetOK = false
795 for i := len(p.oe) - 1; i >= 0; i-- {
796 node := p.oe[i]
797 switch node.DataAtom {
798 case a.Dd, a.Dt:
799 p.oe = p.oe[:i]
800 case a.Address, a.Div, a.P:
801 continue
802 default:
803 if !isSpecialElement(node) {
804 continue
805 }
806 }
807 break
808 }
809 p.popUntil(buttonScope, a.P)
810 p.addElement()
811 case a.Plaintext:
812 p.popUntil(buttonScope, a.P)
813 p.addElement()
814 case a.Button:
815 p.popUntil(defaultScope, a.Button)
816 p.reconstructActiveFormattingElements()
817 p.addElement()
818 p.framesetOK = false
819 case a.A:
820 for i := len(p.afe) - 1; i >= 0 && p.afe[i].Type != scopeMarkerNode; i-- {
821 if n := p.afe[i]; n.Type == ElementNode && n.DataAtom == a.A {
822 p.inBodyEndTagFormatting(a.A)
823 p.oe.remove(n)
824 p.afe.remove(n)
825 break
826 }
827 }
828 p.reconstructActiveFormattingElements()
829 p.addFormattingElement()
830 case a.B, a.Big, a.Code, a.Em, a.Font, a.I, a.S, a.Small, a.Strike, a.Strong, a.Tt, a.U:
831 p.reconstructActiveFormattingElements()
832 p.addFormattingElement()
833 case a.Nobr:
834 p.reconstructActiveFormattingElements()
835 if p.elementInScope(defaultScope, a.Nobr) {
836 p.inBodyEndTagFormatting(a.Nobr)
837 p.reconstructActiveFormattingElements()
838 }
839 p.addFormattingElement()
840 case a.Applet, a.Marquee, a.Object:
841 p.reconstructActiveFormattingElements()
842 p.addElement()
843 p.afe = append(p.afe, &scopeMarker)
844 p.framesetOK = false
845 case a.Table:
846 if !p.quirks {
847 p.popUntil(buttonScope, a.P)
848 }
849 p.addElement()
850 p.framesetOK = false
851 p.im = inTableIM
852 return true
853 case a.Area, a.Br, a.Embed, a.Img, a.Input, a.Keygen, a.Wbr:
854 p.reconstructActiveFormattingElements()
855 p.addElement()
856 p.oe.pop()
857 p.acknowledgeSelfClosingTag()
858 if p.tok.DataAtom == a.Input {
859 for _, t := range p.tok.Attr {
860 if t.Key == "type" {
861 if strings.ToLower(t.Val) == "hidden" {
862 // Skip setting framesetOK = false
863 return true
864 }
865 }
866 }
867 }
868 p.framesetOK = false
869 case a.Param, a.Source, a.Track:
870 p.addElement()
871 p.oe.pop()
872 p.acknowledgeSelfClosingTag()
873 case a.Hr:
874 p.popUntil(buttonScope, a.P)
875 p.addElement()
876 p.oe.pop()
877 p.acknowledgeSelfClosingTag()
878 p.framesetOK = false
879 case a.Image:
880 p.tok.DataAtom = a.Img
881 p.tok.Data = a.Img.String()
882 return false
883 case a.Isindex:
884 if p.form != nil {
885 // Ignore the token.
886 return true
887 }
888 action := ""
889 prompt := "This is a searchable index. Enter search keywords: "
890 attr := []Attribute{{Key: "name", Val: "isindex"}}
891 for _, t := range p.tok.Attr {
892 switch t.Key {
893 case "action":
894 action = t.Val
895 case "name":
896 // Ignore the attribute.
897 case "prompt":
898 prompt = t.Val
899 default:
900 attr = append(attr, t)
901 }
902 }
903 p.acknowledgeSelfClosingTag()
904 p.popUntil(buttonScope, a.P)
905 p.parseImpliedToken(StartTagToken, a.Form, a.Form.String())
906 if action != "" {
907 p.form.Attr = []Attribute{{Key: "action", Val: action}}
908 }
909 p.parseImpliedToken(StartTagToken, a.Hr, a.Hr.String())
910 p.parseImpliedToken(StartTagToken, a.Label, a.Label.String())
911 p.addText(prompt)
912 p.addChild(&Node{
913 Type: ElementNode,
914 DataAtom: a.Input,
915 Data: a.Input.String(),
916 Attr: attr,
917 })
918 p.oe.pop()
919 p.parseImpliedToken(EndTagToken, a.Label, a.Label.String())
920 p.parseImpliedToken(StartTagToken, a.Hr, a.Hr.String())
921 p.parseImpliedToken(EndTagToken, a.Form, a.Form.String())
922 case a.Textarea:
923 p.addElement()
924 p.setOriginalIM()
925 p.framesetOK = false
926 p.im = textIM
927 case a.Xmp:
928 p.popUntil(buttonScope, a.P)
929 p.reconstructActiveFormattingElements()
930 p.framesetOK = false
931 p.addElement()
932 p.setOriginalIM()
933 p.im = textIM
934 case a.Iframe:
935 p.framesetOK = false
936 p.addElement()
937 p.setOriginalIM()
938 p.im = textIM
939 case a.Noembed, a.Noscript:
940 p.addElement()
941 p.setOriginalIM()
942 p.im = textIM
943 case a.Select:
944 p.reconstructActiveFormattingElements()
945 p.addElement()
946 p.framesetOK = false
947 p.im = inSelectIM
948 return true
949 case a.Optgroup, a.Option:
950 if p.top().DataAtom == a.Option {
951 p.oe.pop()
952 }
953 p.reconstructActiveFormattingElements()
954 p.addElement()
955 case a.Rp, a.Rt:
956 if p.elementInScope(defaultScope, a.Ruby) {
957 p.generateImpliedEndTags()
958 }
959 p.addElement()
960 case a.Math, a.Svg:
961 p.reconstructActiveFormattingElements()
962 if p.tok.DataAtom == a.Math {
963 adjustAttributeNames(p.tok.Attr, mathMLAttributeAdjustments)
964 } else {
965 adjustAttributeNames(p.tok.Attr, svgAttributeAdjustments)
966 }
967 adjustForeignAttributes(p.tok.Attr)
968 p.addElement()
969 p.top().Namespace = p.tok.Data
970 if p.hasSelfClosingToken {
971 p.oe.pop()
972 p.acknowledgeSelfClosingTag()
973 }
974 return true
975 case a.Caption, a.Col, a.Colgroup, a.Frame, a.Head, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr:
976 // Ignore the token.
977 default:
978 p.reconstructActiveFormattingElements()
979 p.addElement()
980 }
981 case EndTagToken:
982 switch p.tok.DataAtom {
983 case a.Body:
984 if p.elementInScope(defaultScope, a.Body) {
985 p.im = afterBodyIM
986 }
987 case a.Html:
988 if p.elementInScope(defaultScope, a.Body) {
989 p.parseImpliedToken(EndTagToken, a.Body, a.Body.String())
990 return false
991 }
992 return true
993 case a.Address, a.Article, a.Aside, a.Blockquote, a.Button, a.Center, a.Details, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Listing, a.Menu, a.Nav, a.Ol, a.Pre, a.Section, a.Summary, a.Ul:
994 p.popUntil(defaultScope, p.tok.DataAtom)
995 case a.Form:
996 node := p.form
997 p.form = nil
998 i := p.indexOfElementInScope(defaultScope, a.Form)
999 if node == nil || i == -1 || p.oe[i] != node {
1000 // Ignore the token.
1001 return true
1002 }
1003 p.generateImpliedEndTags()
1004 p.oe.remove(node)
1005 case a.P:
1006 if !p.elementInScope(buttonScope, a.P) {
1007 p.parseImpliedToken(StartTagToken, a.P, a.P.String())
1008 }
1009 p.popUntil(buttonScope, a.P)
1010 case a.Li:
1011 p.popUntil(listItemScope, a.Li)
1012 case a.Dd, a.Dt:
1013 p.popUntil(defaultScope, p.tok.DataAtom)
1014 case a.H1, a.H2, a.H3, a.H4, a.H5, a.H6:
1015 p.popUntil(defaultScope, a.H1, a.H2, a.H3, a.H4, a.H5, a.H6)
1016 case a.A, a.B, a.Big, a.Code, a.Em, a.Font, a.I, a.Nobr, a.S, a.Small, a.Strike, a.Strong, a.Tt, a.U:
1017 p.inBodyEndTagFormatting(p.tok.DataAtom)
1018 case a.Applet, a.Marquee, a.Object:
1019 if p.popUntil(defaultScope, p.tok.DataAtom) {
1020 p.clearActiveFormattingElements()
1021 }
1022 case a.Br:
1023 p.tok.Type = StartTagToken
1024 return false
1025 default:
1026 p.inBodyEndTagOther(p.tok.DataAtom)
1027 }
1028 case CommentToken:
1029 p.addChild(&Node{
1030 Type: CommentNode,
1031 Data: p.tok.Data,
1032 })
1033 }
1034
1035 return true
1036}
1037
1038func (p *parser) inBodyEndTagFormatting(tagAtom a.Atom) {
1039 // This is the "adoption agency" algorithm, described at
1040 // https://html.spec.whatwg.org/multipage/syntax.html#adoptionAgency
1041
1042 // TODO: this is a fairly literal line-by-line translation of that algorithm.
1043 // Once the code successfully parses the comprehensive test suite, we should
1044 // refactor this code to be more idiomatic.
1045
1046 // Steps 1-4. The outer loop.
1047 for i := 0; i < 8; i++ {
1048 // Step 5. Find the formatting element.
1049 var formattingElement *Node
1050 for j := len(p.afe) - 1; j >= 0; j-- {
1051 if p.afe[j].Type == scopeMarkerNode {
1052 break
1053 }
1054 if p.afe[j].DataAtom == tagAtom {
1055 formattingElement = p.afe[j]
1056 break
1057 }
1058 }
1059 if formattingElement == nil {
1060 p.inBodyEndTagOther(tagAtom)
1061 return
1062 }
1063 feIndex := p.oe.index(formattingElement)
1064 if feIndex == -1 {
1065 p.afe.remove(formattingElement)
1066 return
1067 }
1068 if !p.elementInScope(defaultScope, tagAtom) {
1069 // Ignore the tag.
1070 return
1071 }
1072
1073 // Steps 9-10. Find the furthest block.
1074 var furthestBlock *Node
1075 for _, e := range p.oe[feIndex:] {
1076 if isSpecialElement(e) {
1077 furthestBlock = e
1078 break
1079 }
1080 }
1081 if furthestBlock == nil {
1082 e := p.oe.pop()
1083 for e != formattingElement {
1084 e = p.oe.pop()
1085 }
1086 p.afe.remove(e)
1087 return
1088 }
1089
1090 // Steps 11-12. Find the common ancestor and bookmark node.
1091 commonAncestor := p.oe[feIndex-1]
1092 bookmark := p.afe.index(formattingElement)
1093
1094 // Step 13. The inner loop. Find the lastNode to reparent.
1095 lastNode := furthestBlock
1096 node := furthestBlock
1097 x := p.oe.index(node)
1098 // Steps 13.1-13.2
1099 for j := 0; j < 3; j++ {
1100 // Step 13.3.
1101 x--
1102 node = p.oe[x]
1103 // Step 13.4 - 13.5.
1104 if p.afe.index(node) == -1 {
1105 p.oe.remove(node)
1106 continue
1107 }
1108 // Step 13.6.
1109 if node == formattingElement {
1110 break
1111 }
1112 // Step 13.7.
1113 clone := node.clone()
1114 p.afe[p.afe.index(node)] = clone
1115 p.oe[p.oe.index(node)] = clone
1116 node = clone
1117 // Step 13.8.
1118 if lastNode == furthestBlock {
1119 bookmark = p.afe.index(node) + 1
1120 }
1121 // Step 13.9.
1122 if lastNode.Parent != nil {
1123 lastNode.Parent.RemoveChild(lastNode)
1124 }
1125 node.AppendChild(lastNode)
1126 // Step 13.10.
1127 lastNode = node
1128 }
1129
1130 // Step 14. Reparent lastNode to the common ancestor,
1131 // or for misnested table nodes, to the foster parent.
1132 if lastNode.Parent != nil {
1133 lastNode.Parent.RemoveChild(lastNode)
1134 }
1135 switch commonAncestor.DataAtom {
1136 case a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr:
1137 p.fosterParent(lastNode)
1138 default:
1139 commonAncestor.AppendChild(lastNode)
1140 }
1141
1142 // Steps 15-17. Reparent nodes from the furthest block's children
1143 // to a clone of the formatting element.
1144 clone := formattingElement.clone()
1145 reparentChildren(clone, furthestBlock)
1146 furthestBlock.AppendChild(clone)
1147
1148 // Step 18. Fix up the list of active formatting elements.
1149 if oldLoc := p.afe.index(formattingElement); oldLoc != -1 && oldLoc < bookmark {
1150 // Move the bookmark with the rest of the list.
1151 bookmark--
1152 }
1153 p.afe.remove(formattingElement)
1154 p.afe.insert(bookmark, clone)
1155
1156 // Step 19. Fix up the stack of open elements.
1157 p.oe.remove(formattingElement)
1158 p.oe.insert(p.oe.index(furthestBlock)+1, clone)
1159 }
1160}
1161
1162// inBodyEndTagOther performs the "any other end tag" algorithm for inBodyIM.
1163// "Any other end tag" handling from 12.2.5.5 The rules for parsing tokens in foreign content
1164// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inforeign
1165func (p *parser) inBodyEndTagOther(tagAtom a.Atom) {
1166 for i := len(p.oe) - 1; i >= 0; i-- {
1167 if p.oe[i].DataAtom == tagAtom {
1168 p.oe = p.oe[:i]
1169 break
1170 }
1171 if isSpecialElement(p.oe[i]) {
1172 break
1173 }
1174 }
1175}
1176
1177// Section 12.2.5.4.8.
1178func textIM(p *parser) bool {
1179 switch p.tok.Type {
1180 case ErrorToken:
1181 p.oe.pop()
1182 case TextToken:
1183 d := p.tok.Data
1184 if n := p.oe.top(); n.DataAtom == a.Textarea && n.FirstChild == nil {
1185 // Ignore a newline at the start of a <textarea> block.
1186 if d != "" && d[0] == '\r' {
1187 d = d[1:]
1188 }
1189 if d != "" && d[0] == '\n' {
1190 d = d[1:]
1191 }
1192 }
1193 if d == "" {
1194 return true
1195 }
1196 p.addText(d)
1197 return true
1198 case EndTagToken:
1199 p.oe.pop()
1200 }
1201 p.im = p.originalIM
1202 p.originalIM = nil
1203 return p.tok.Type == EndTagToken
1204}
1205
1206// Section 12.2.5.4.9.
1207func inTableIM(p *parser) bool {
1208 switch p.tok.Type {
1209 case ErrorToken:
1210 // Stop parsing.
1211 return true
1212 case TextToken:
1213 p.tok.Data = strings.Replace(p.tok.Data, "\x00", "", -1)
1214 switch p.oe.top().DataAtom {
1215 case a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr:
1216 if strings.Trim(p.tok.Data, whitespace) == "" {
1217 p.addText(p.tok.Data)
1218 return true
1219 }
1220 }
1221 case StartTagToken:
1222 switch p.tok.DataAtom {
1223 case a.Caption:
1224 p.clearStackToContext(tableScope)
1225 p.afe = append(p.afe, &scopeMarker)
1226 p.addElement()
1227 p.im = inCaptionIM
1228 return true
1229 case a.Colgroup:
1230 p.clearStackToContext(tableScope)
1231 p.addElement()
1232 p.im = inColumnGroupIM
1233 return true
1234 case a.Col:
1235 p.parseImpliedToken(StartTagToken, a.Colgroup, a.Colgroup.String())
1236 return false
1237 case a.Tbody, a.Tfoot, a.Thead:
1238 p.clearStackToContext(tableScope)
1239 p.addElement()
1240 p.im = inTableBodyIM
1241 return true
1242 case a.Td, a.Th, a.Tr:
1243 p.parseImpliedToken(StartTagToken, a.Tbody, a.Tbody.String())
1244 return false
1245 case a.Table:
1246 if p.popUntil(tableScope, a.Table) {
1247 p.resetInsertionMode()
1248 return false
1249 }
1250 // Ignore the token.
1251 return true
1252 case a.Style, a.Script:
1253 return inHeadIM(p)
1254 case a.Input:
1255 for _, t := range p.tok.Attr {
1256 if t.Key == "type" && strings.ToLower(t.Val) == "hidden" {
1257 p.addElement()
1258 p.oe.pop()
1259 return true
1260 }
1261 }
1262 // Otherwise drop down to the default action.
1263 case a.Form:
1264 if p.form != nil {
1265 // Ignore the token.
1266 return true
1267 }
1268 p.addElement()
1269 p.form = p.oe.pop()
1270 case a.Select:
1271 p.reconstructActiveFormattingElements()
1272 switch p.top().DataAtom {
1273 case a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr:
1274 p.fosterParenting = true
1275 }
1276 p.addElement()
1277 p.fosterParenting = false
1278 p.framesetOK = false
1279 p.im = inSelectInTableIM
1280 return true
1281 }
1282 case EndTagToken:
1283 switch p.tok.DataAtom {
1284 case a.Table:
1285 if p.popUntil(tableScope, a.Table) {
1286 p.resetInsertionMode()
1287 return true
1288 }
1289 // Ignore the token.
1290 return true
1291 case a.Body, a.Caption, a.Col, a.Colgroup, a.Html, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr:
1292 // Ignore the token.
1293 return true
1294 }
1295 case CommentToken:
1296 p.addChild(&Node{
1297 Type: CommentNode,
1298 Data: p.tok.Data,
1299 })
1300 return true
1301 case DoctypeToken:
1302 // Ignore the token.
1303 return true
1304 }
1305
1306 p.fosterParenting = true
1307 defer func() { p.fosterParenting = false }()
1308
1309 return inBodyIM(p)
1310}
1311
1312// Section 12.2.5.4.11.
1313func inCaptionIM(p *parser) bool {
1314 switch p.tok.Type {
1315 case StartTagToken:
1316 switch p.tok.DataAtom {
1317 case a.Caption, a.Col, a.Colgroup, a.Tbody, a.Td, a.Tfoot, a.Thead, a.Tr:
1318 if p.popUntil(tableScope, a.Caption) {
1319 p.clearActiveFormattingElements()
1320 p.im = inTableIM
1321 return false
1322 } else {
1323 // Ignore the token.
1324 return true
1325 }
1326 case a.Select:
1327 p.reconstructActiveFormattingElements()
1328 p.addElement()
1329 p.framesetOK = false
1330 p.im = inSelectInTableIM
1331 return true
1332 }
1333 case EndTagToken:
1334 switch p.tok.DataAtom {
1335 case a.Caption:
1336 if p.popUntil(tableScope, a.Caption) {
1337 p.clearActiveFormattingElements()
1338 p.im = inTableIM
1339 }
1340 return true
1341 case a.Table:
1342 if p.popUntil(tableScope, a.Caption) {
1343 p.clearActiveFormattingElements()
1344 p.im = inTableIM
1345 return false
1346 } else {
1347 // Ignore the token.
1348 return true
1349 }
1350 case a.Body, a.Col, a.Colgroup, a.Html, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr:
1351 // Ignore the token.
1352 return true
1353 }
1354 }
1355 return inBodyIM(p)
1356}
1357
1358// Section 12.2.5.4.12.
1359func inColumnGroupIM(p *parser) bool {
1360 switch p.tok.Type {
1361 case TextToken:
1362 s := strings.TrimLeft(p.tok.Data, whitespace)
1363 if len(s) < len(p.tok.Data) {
1364 // Add the initial whitespace to the current node.
1365 p.addText(p.tok.Data[:len(p.tok.Data)-len(s)])
1366 if s == "" {
1367 return true
1368 }
1369 p.tok.Data = s
1370 }
1371 case CommentToken:
1372 p.addChild(&Node{
1373 Type: CommentNode,
1374 Data: p.tok.Data,
1375 })
1376 return true
1377 case DoctypeToken:
1378 // Ignore the token.
1379 return true
1380 case StartTagToken:
1381 switch p.tok.DataAtom {
1382 case a.Html:
1383 return inBodyIM(p)
1384 case a.Col:
1385 p.addElement()
1386 p.oe.pop()
1387 p.acknowledgeSelfClosingTag()
1388 return true
1389 }
1390 case EndTagToken:
1391 switch p.tok.DataAtom {
1392 case a.Colgroup:
1393 if p.oe.top().DataAtom != a.Html {
1394 p.oe.pop()
1395 p.im = inTableIM
1396 }
1397 return true
1398 case a.Col:
1399 // Ignore the token.
1400 return true
1401 }
1402 }
1403 if p.oe.top().DataAtom != a.Html {
1404 p.oe.pop()
1405 p.im = inTableIM
1406 return false
1407 }
1408 return true
1409}
1410
1411// Section 12.2.5.4.13.
1412func inTableBodyIM(p *parser) bool {
1413 switch p.tok.Type {
1414 case StartTagToken:
1415 switch p.tok.DataAtom {
1416 case a.Tr:
1417 p.clearStackToContext(tableBodyScope)
1418 p.addElement()
1419 p.im = inRowIM
1420 return true
1421 case a.Td, a.Th:
1422 p.parseImpliedToken(StartTagToken, a.Tr, a.Tr.String())
1423 return false
1424 case a.Caption, a.Col, a.Colgroup, a.Tbody, a.Tfoot, a.Thead:
1425 if p.popUntil(tableScope, a.Tbody, a.Thead, a.Tfoot) {
1426 p.im = inTableIM
1427 return false
1428 }
1429 // Ignore the token.
1430 return true
1431 }
1432 case EndTagToken:
1433 switch p.tok.DataAtom {
1434 case a.Tbody, a.Tfoot, a.Thead:
1435 if p.elementInScope(tableScope, p.tok.DataAtom) {
1436 p.clearStackToContext(tableBodyScope)
1437 p.oe.pop()
1438 p.im = inTableIM
1439 }
1440 return true
1441 case a.Table:
1442 if p.popUntil(tableScope, a.Tbody, a.Thead, a.Tfoot) {
1443 p.im = inTableIM
1444 return false
1445 }
1446 // Ignore the token.
1447 return true
1448 case a.Body, a.Caption, a.Col, a.Colgroup, a.Html, a.Td, a.Th, a.Tr:
1449 // Ignore the token.
1450 return true
1451 }
1452 case CommentToken:
1453 p.addChild(&Node{
1454 Type: CommentNode,
1455 Data: p.tok.Data,
1456 })
1457 return true
1458 }
1459
1460 return inTableIM(p)
1461}
1462
1463// Section 12.2.5.4.14.
1464func inRowIM(p *parser) bool {
1465 switch p.tok.Type {
1466 case StartTagToken:
1467 switch p.tok.DataAtom {
1468 case a.Td, a.Th:
1469 p.clearStackToContext(tableRowScope)
1470 p.addElement()
1471 p.afe = append(p.afe, &scopeMarker)
1472 p.im = inCellIM
1473 return true
1474 case a.Caption, a.Col, a.Colgroup, a.Tbody, a.Tfoot, a.Thead, a.Tr:
1475 if p.popUntil(tableScope, a.Tr) {
1476 p.im = inTableBodyIM
1477 return false
1478 }
1479 // Ignore the token.
1480 return true
1481 }
1482 case EndTagToken:
1483 switch p.tok.DataAtom {
1484 case a.Tr:
1485 if p.popUntil(tableScope, a.Tr) {
1486 p.im = inTableBodyIM
1487 return true
1488 }
1489 // Ignore the token.
1490 return true
1491 case a.Table:
1492 if p.popUntil(tableScope, a.Tr) {
1493 p.im = inTableBodyIM
1494 return false
1495 }
1496 // Ignore the token.
1497 return true
1498 case a.Tbody, a.Tfoot, a.Thead:
1499 if p.elementInScope(tableScope, p.tok.DataAtom) {
1500 p.parseImpliedToken(EndTagToken, a.Tr, a.Tr.String())
1501 return false
1502 }
1503 // Ignore the token.
1504 return true
1505 case a.Body, a.Caption, a.Col, a.Colgroup, a.Html, a.Td, a.Th:
1506 // Ignore the token.
1507 return true
1508 }
1509 }
1510
1511 return inTableIM(p)
1512}
1513
1514// Section 12.2.5.4.15.
1515func inCellIM(p *parser) bool {
1516 switch p.tok.Type {
1517 case StartTagToken:
1518 switch p.tok.DataAtom {
1519 case a.Caption, a.Col, a.Colgroup, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr:
1520 if p.popUntil(tableScope, a.Td, a.Th) {
1521 // Close the cell and reprocess.
1522 p.clearActiveFormattingElements()
1523 p.im = inRowIM
1524 return false
1525 }
1526 // Ignore the token.
1527 return true
1528 case a.Select:
1529 p.reconstructActiveFormattingElements()
1530 p.addElement()
1531 p.framesetOK = false
1532 p.im = inSelectInTableIM
1533 return true
1534 }
1535 case EndTagToken:
1536 switch p.tok.DataAtom {
1537 case a.Td, a.Th:
1538 if !p.popUntil(tableScope, p.tok.DataAtom) {
1539 // Ignore the token.
1540 return true
1541 }
1542 p.clearActiveFormattingElements()
1543 p.im = inRowIM
1544 return true
1545 case a.Body, a.Caption, a.Col, a.Colgroup, a.Html:
1546 // Ignore the token.
1547 return true
1548 case a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr:
1549 if !p.elementInScope(tableScope, p.tok.DataAtom) {
1550 // Ignore the token.
1551 return true
1552 }
1553 // Close the cell and reprocess.
1554 p.popUntil(tableScope, a.Td, a.Th)
1555 p.clearActiveFormattingElements()
1556 p.im = inRowIM
1557 return false
1558 }
1559 }
1560 return inBodyIM(p)
1561}
1562
1563// Section 12.2.5.4.16.
1564func inSelectIM(p *parser) bool {
1565 switch p.tok.Type {
1566 case ErrorToken:
1567 // Stop parsing.
1568 return true
1569 case TextToken:
1570 p.addText(strings.Replace(p.tok.Data, "\x00", "", -1))
1571 case StartTagToken:
1572 switch p.tok.DataAtom {
1573 case a.Html:
1574 return inBodyIM(p)
1575 case a.Option:
1576 if p.top().DataAtom == a.Option {
1577 p.oe.pop()
1578 }
1579 p.addElement()
1580 case a.Optgroup:
1581 if p.top().DataAtom == a.Option {
1582 p.oe.pop()
1583 }
1584 if p.top().DataAtom == a.Optgroup {
1585 p.oe.pop()
1586 }
1587 p.addElement()
1588 case a.Select:
1589 p.tok.Type = EndTagToken
1590 return false
1591 case a.Input, a.Keygen, a.Textarea:
1592 if p.elementInScope(selectScope, a.Select) {
1593 p.parseImpliedToken(EndTagToken, a.Select, a.Select.String())
1594 return false
1595 }
1596 // In order to properly ignore <textarea>, we need to change the tokenizer mode.
1597 p.tokenizer.NextIsNotRawText()
1598 // Ignore the token.
1599 return true
1600 case a.Script:
1601 return inHeadIM(p)
1602 }
1603 case EndTagToken:
1604 switch p.tok.DataAtom {
1605 case a.Option:
1606 if p.top().DataAtom == a.Option {
1607 p.oe.pop()
1608 }
1609 case a.Optgroup:
1610 i := len(p.oe) - 1
1611 if p.oe[i].DataAtom == a.Option {
1612 i--
1613 }
1614 if p.oe[i].DataAtom == a.Optgroup {
1615 p.oe = p.oe[:i]
1616 }
1617 case a.Select:
1618 if p.popUntil(selectScope, a.Select) {
1619 p.resetInsertionMode()
1620 }
1621 }
1622 case CommentToken:
1623 p.addChild(&Node{
1624 Type: CommentNode,
1625 Data: p.tok.Data,
1626 })
1627 case DoctypeToken:
1628 // Ignore the token.
1629 return true
1630 }
1631
1632 return true
1633}
1634
1635// Section 12.2.5.4.17.
1636func inSelectInTableIM(p *parser) bool {
1637 switch p.tok.Type {
1638 case StartTagToken, EndTagToken:
1639 switch p.tok.DataAtom {
1640 case a.Caption, a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr, a.Td, a.Th:
1641 if p.tok.Type == StartTagToken || p.elementInScope(tableScope, p.tok.DataAtom) {
1642 p.parseImpliedToken(EndTagToken, a.Select, a.Select.String())
1643 return false
1644 } else {
1645 // Ignore the token.
1646 return true
1647 }
1648 }
1649 }
1650 return inSelectIM(p)
1651}
1652
1653// Section 12.2.5.4.18.
1654func afterBodyIM(p *parser) bool {
1655 switch p.tok.Type {
1656 case ErrorToken:
1657 // Stop parsing.
1658 return true
1659 case TextToken:
1660 s := strings.TrimLeft(p.tok.Data, whitespace)
1661 if len(s) == 0 {
1662 // It was all whitespace.
1663 return inBodyIM(p)
1664 }
1665 case StartTagToken:
1666 if p.tok.DataAtom == a.Html {
1667 return inBodyIM(p)
1668 }
1669 case EndTagToken:
1670 if p.tok.DataAtom == a.Html {
1671 if !p.fragment {
1672 p.im = afterAfterBodyIM
1673 }
1674 return true
1675 }
1676 case CommentToken:
1677 // The comment is attached to the <html> element.
1678 if len(p.oe) < 1 || p.oe[0].DataAtom != a.Html {
1679 panic("html: bad parser state: <html> element not found, in the after-body insertion mode")
1680 }
1681 p.oe[0].AppendChild(&Node{
1682 Type: CommentNode,
1683 Data: p.tok.Data,
1684 })
1685 return true
1686 }
1687 p.im = inBodyIM
1688 return false
1689}
1690
1691// Section 12.2.5.4.19.
1692func inFramesetIM(p *parser) bool {
1693 switch p.tok.Type {
1694 case CommentToken:
1695 p.addChild(&Node{
1696 Type: CommentNode,
1697 Data: p.tok.Data,
1698 })
1699 case TextToken:
1700 // Ignore all text but whitespace.
1701 s := strings.Map(func(c rune) rune {
1702 switch c {
1703 case ' ', '\t', '\n', '\f', '\r':
1704 return c
1705 }
1706 return -1
1707 }, p.tok.Data)
1708 if s != "" {
1709 p.addText(s)
1710 }
1711 case StartTagToken:
1712 switch p.tok.DataAtom {
1713 case a.Html:
1714 return inBodyIM(p)
1715 case a.Frameset:
1716 p.addElement()
1717 case a.Frame:
1718 p.addElement()
1719 p.oe.pop()
1720 p.acknowledgeSelfClosingTag()
1721 case a.Noframes:
1722 return inHeadIM(p)
1723 }
1724 case EndTagToken:
1725 switch p.tok.DataAtom {
1726 case a.Frameset:
1727 if p.oe.top().DataAtom != a.Html {
1728 p.oe.pop()
1729 if p.oe.top().DataAtom != a.Frameset {
1730 p.im = afterFramesetIM
1731 return true
1732 }
1733 }
1734 }
1735 default:
1736 // Ignore the token.
1737 }
1738 return true
1739}
1740
1741// Section 12.2.5.4.20.
1742func afterFramesetIM(p *parser) bool {
1743 switch p.tok.Type {
1744 case CommentToken:
1745 p.addChild(&Node{
1746 Type: CommentNode,
1747 Data: p.tok.Data,
1748 })
1749 case TextToken:
1750 // Ignore all text but whitespace.
1751 s := strings.Map(func(c rune) rune {
1752 switch c {
1753 case ' ', '\t', '\n', '\f', '\r':
1754 return c
1755 }
1756 return -1
1757 }, p.tok.Data)
1758 if s != "" {
1759 p.addText(s)
1760 }
1761 case StartTagToken:
1762 switch p.tok.DataAtom {
1763 case a.Html:
1764 return inBodyIM(p)
1765 case a.Noframes:
1766 return inHeadIM(p)
1767 }
1768 case EndTagToken:
1769 switch p.tok.DataAtom {
1770 case a.Html:
1771 p.im = afterAfterFramesetIM
1772 return true
1773 }
1774 default:
1775 // Ignore the token.
1776 }
1777 return true
1778}
1779
1780// Section 12.2.5.4.21.
1781func afterAfterBodyIM(p *parser) bool {
1782 switch p.tok.Type {
1783 case ErrorToken:
1784 // Stop parsing.
1785 return true
1786 case TextToken:
1787 s := strings.TrimLeft(p.tok.Data, whitespace)
1788 if len(s) == 0 {
1789 // It was all whitespace.
1790 return inBodyIM(p)
1791 }
1792 case StartTagToken:
1793 if p.tok.DataAtom == a.Html {
1794 return inBodyIM(p)
1795 }
1796 case CommentToken:
1797 p.doc.AppendChild(&Node{
1798 Type: CommentNode,
1799 Data: p.tok.Data,
1800 })
1801 return true
1802 case DoctypeToken:
1803 return inBodyIM(p)
1804 }
1805 p.im = inBodyIM
1806 return false
1807}
1808
1809// Section 12.2.5.4.22.
1810func afterAfterFramesetIM(p *parser) bool {
1811 switch p.tok.Type {
1812 case CommentToken:
1813 p.doc.AppendChild(&Node{
1814 Type: CommentNode,
1815 Data: p.tok.Data,
1816 })
1817 case TextToken:
1818 // Ignore all text but whitespace.
1819 s := strings.Map(func(c rune) rune {
1820 switch c {
1821 case ' ', '\t', '\n', '\f', '\r':
1822 return c
1823 }
1824 return -1
1825 }, p.tok.Data)
1826 if s != "" {
1827 p.tok.Data = s
1828 return inBodyIM(p)
1829 }
1830 case StartTagToken:
1831 switch p.tok.DataAtom {
1832 case a.Html:
1833 return inBodyIM(p)
1834 case a.Noframes:
1835 return inHeadIM(p)
1836 }
1837 case DoctypeToken:
1838 return inBodyIM(p)
1839 default:
1840 // Ignore the token.
1841 }
1842 return true
1843}
1844
1845const whitespaceOrNUL = whitespace + "\x00"
1846
1847// Section 12.2.5.5.
1848func parseForeignContent(p *parser) bool {
1849 switch p.tok.Type {
1850 case TextToken:
1851 if p.framesetOK {
1852 p.framesetOK = strings.TrimLeft(p.tok.Data, whitespaceOrNUL) == ""
1853 }
1854 p.tok.Data = strings.Replace(p.tok.Data, "\x00", "\ufffd", -1)
1855 p.addText(p.tok.Data)
1856 case CommentToken:
1857 p.addChild(&Node{
1858 Type: CommentNode,
1859 Data: p.tok.Data,
1860 })
1861 case StartTagToken:
1862 b := breakout[p.tok.Data]
1863 if p.tok.DataAtom == a.Font {
1864 loop:
1865 for _, attr := range p.tok.Attr {
1866 switch attr.Key {
1867 case "color", "face", "size":
1868 b = true
1869 break loop
1870 }
1871 }
1872 }
1873 if b {
1874 for i := len(p.oe) - 1; i >= 0; i-- {
1875 n := p.oe[i]
1876 if n.Namespace == "" || htmlIntegrationPoint(n) || mathMLTextIntegrationPoint(n) {
1877 p.oe = p.oe[:i+1]
1878 break
1879 }
1880 }
1881 return false
1882 }
1883 switch p.top().Namespace {
1884 case "math":
1885 adjustAttributeNames(p.tok.Attr, mathMLAttributeAdjustments)
1886 case "svg":
1887 // Adjust SVG tag names. The tokenizer lower-cases tag names, but
1888 // SVG wants e.g. "foreignObject" with a capital second "O".
1889 if x := svgTagNameAdjustments[p.tok.Data]; x != "" {
1890 p.tok.DataAtom = a.Lookup([]byte(x))
1891 p.tok.Data = x
1892 }
1893 adjustAttributeNames(p.tok.Attr, svgAttributeAdjustments)
1894 default:
1895 panic("html: bad parser state: unexpected namespace")
1896 }
1897 adjustForeignAttributes(p.tok.Attr)
1898 namespace := p.top().Namespace
1899 p.addElement()
1900 p.top().Namespace = namespace
1901 if namespace != "" {
1902 // Don't let the tokenizer go into raw text mode in foreign content
1903 // (e.g. in an SVG <title> tag).
1904 p.tokenizer.NextIsNotRawText()
1905 }
1906 if p.hasSelfClosingToken {
1907 p.oe.pop()
1908 p.acknowledgeSelfClosingTag()
1909 }
1910 case EndTagToken:
1911 for i := len(p.oe) - 1; i >= 0; i-- {
1912 if p.oe[i].Namespace == "" {
1913 return p.im(p)
1914 }
1915 if strings.EqualFold(p.oe[i].Data, p.tok.Data) {
1916 p.oe = p.oe[:i]
1917 break
1918 }
1919 }
1920 return true
1921 default:
1922 // Ignore the token.
1923 }
1924 return true
1925}
1926
1927// Section 12.2.5.
1928func (p *parser) inForeignContent() bool {
1929 if len(p.oe) == 0 {
1930 return false
1931 }
1932 n := p.oe[len(p.oe)-1]
1933 if n.Namespace == "" {
1934 return false
1935 }
1936 if mathMLTextIntegrationPoint(n) {
1937 if p.tok.Type == StartTagToken && p.tok.DataAtom != a.Mglyph && p.tok.DataAtom != a.Malignmark {
1938 return false
1939 }
1940 if p.tok.Type == TextToken {
1941 return false
1942 }
1943 }
1944 if n.Namespace == "math" && n.DataAtom == a.AnnotationXml && p.tok.Type == StartTagToken && p.tok.DataAtom == a.Svg {
1945 return false
1946 }
1947 if htmlIntegrationPoint(n) && (p.tok.Type == StartTagToken || p.tok.Type == TextToken) {
1948 return false
1949 }
1950 if p.tok.Type == ErrorToken {
1951 return false
1952 }
1953 return true
1954}
1955
1956// parseImpliedToken parses a token as though it had appeared in the parser's
1957// input.
1958func (p *parser) parseImpliedToken(t TokenType, dataAtom a.Atom, data string) {
1959 realToken, selfClosing := p.tok, p.hasSelfClosingToken
1960 p.tok = Token{
1961 Type: t,
1962 DataAtom: dataAtom,
1963 Data: data,
1964 }
1965 p.hasSelfClosingToken = false
1966 p.parseCurrentToken()
1967 p.tok, p.hasSelfClosingToken = realToken, selfClosing
1968}
1969
1970// parseCurrentToken runs the current token through the parsing routines
1971// until it is consumed.
1972func (p *parser) parseCurrentToken() {
1973 if p.tok.Type == SelfClosingTagToken {
1974 p.hasSelfClosingToken = true
1975 p.tok.Type = StartTagToken
1976 }
1977
1978 consumed := false
1979 for !consumed {
1980 if p.inForeignContent() {
1981 consumed = parseForeignContent(p)
1982 } else {
1983 consumed = p.im(p)
1984 }
1985 }
1986
1987 if p.hasSelfClosingToken {
1988 // This is a parse error, but ignore it.
1989 p.hasSelfClosingToken = false
1990 }
1991}
1992
1993func (p *parser) parse() error {
1994 // Iterate until EOF. Any other error will cause an early return.
1995 var err error
1996 for err != io.EOF {
1997 // CDATA sections are allowed only in foreign content.
1998 n := p.oe.top()
1999 p.tokenizer.AllowCDATA(n != nil && n.Namespace != "")
2000 // Read and parse the next token.
2001 p.tokenizer.Next()
2002 p.tok = p.tokenizer.Token()
2003 if p.tok.Type == ErrorToken {
2004 err = p.tokenizer.Err()
2005 if err != nil && err != io.EOF {
2006 return err
2007 }
2008 }
2009 p.parseCurrentToken()
2010 }
2011 return nil
2012}
2013
2014// Parse returns the parse tree for the HTML from the given Reader.
2015// The input is assumed to be UTF-8 encoded.
2016func Parse(r io.Reader) (*Node, error) {
2017 p := &parser{
2018 tokenizer: NewTokenizer(r),
2019 doc: &Node{
2020 Type: DocumentNode,
2021 },
2022 scripting: true,
2023 framesetOK: true,
2024 im: initialIM,
2025 }
2026 err := p.parse()
2027 if err != nil {
2028 return nil, err
2029 }
2030 return p.doc, nil
2031}
2032
2033// ParseFragment parses a fragment of HTML and returns the nodes that were
2034// found. If the fragment is the InnerHTML for an existing element, pass that
2035// element in context.
2036func ParseFragment(r io.Reader, context *Node) ([]*Node, error) {
2037 contextTag := ""
2038 if context != nil {
2039 if context.Type != ElementNode {
2040 return nil, errors.New("html: ParseFragment of non-element Node")
2041 }
2042 // The next check isn't just context.DataAtom.String() == context.Data because
2043 // it is valid to pass an element whose tag isn't a known atom. For example,
2044 // DataAtom == 0 and Data = "tagfromthefuture" is perfectly consistent.
2045 if context.DataAtom != a.Lookup([]byte(context.Data)) {
2046 return nil, fmt.Errorf("html: inconsistent Node: DataAtom=%q, Data=%q", context.DataAtom, context.Data)
2047 }
2048 contextTag = context.DataAtom.String()
2049 }
2050 p := &parser{
2051 tokenizer: NewTokenizerFragment(r, contextTag),
2052 doc: &Node{
2053 Type: DocumentNode,
2054 },
2055 scripting: true,
2056 fragment: true,
2057 context: context,
2058 }
2059
2060 root := &Node{
2061 Type: ElementNode,
2062 DataAtom: a.Html,
2063 Data: a.Html.String(),
2064 }
2065 p.doc.AppendChild(root)
2066 p.oe = nodeStack{root}
2067 p.resetInsertionMode()
2068
2069 for n := context; n != nil; n = n.Parent {
2070 if n.Type == ElementNode && n.DataAtom == a.Form {
2071 p.form = n
2072 break
2073 }
2074 }
2075
2076 err := p.parse()
2077 if err != nil {
2078 return nil, err
2079 }
2080
2081 parent := p.doc
2082 if context != nil {
2083 parent = root
2084 }
2085
2086 var result []*Node
2087 for c := parent.FirstChild; c != nil; {
2088 next := c.NextSibling
2089 parent.RemoveChild(c)
2090 result = append(result, c)
2091 c = next
2092 }
2093 return result, nil
2094}
diff --git a/vendor/golang.org/x/net/html/render.go b/vendor/golang.org/x/net/html/render.go
new file mode 100644
index 0000000..d34564f
--- /dev/null
+++ b/vendor/golang.org/x/net/html/render.go
@@ -0,0 +1,271 @@
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
5package html
6
7import (
8 "bufio"
9 "errors"
10 "fmt"
11 "io"
12 "strings"
13)
14
15type writer interface {
16 io.Writer
17 io.ByteWriter
18 WriteString(string) (int, error)
19}
20
21// Render renders the parse tree n to the given writer.
22//
23// Rendering is done on a 'best effort' basis: calling Parse on the output of
24// Render will always result in something similar to the original tree, but it
25// is not necessarily an exact clone unless the original tree was 'well-formed'.
26// 'Well-formed' is not easily specified; the HTML5 specification is
27// complicated.
28//
29// Calling Parse on arbitrary input typically results in a 'well-formed' parse
30// tree. However, it is possible for Parse to yield a 'badly-formed' parse tree.
31// For example, in a 'well-formed' parse tree, no <a> element is a child of
32// another <a> element: parsing "<a><a>" results in two sibling elements.
33// Similarly, in a 'well-formed' parse tree, no <a> element is a child of a
34// <table> element: parsing "<p><table><a>" results in a <p> with two sibling
35// children; the <a> is reparented to the <table>'s parent. However, calling
36// Parse on "<a><table><a>" does not return an error, but the result has an <a>
37// element with an <a> child, and is therefore not 'well-formed'.
38//
39// Programmatically constructed trees are typically also 'well-formed', but it
40// is possible to construct a tree that looks innocuous but, when rendered and
41// re-parsed, results in a different tree. A simple example is that a solitary
42// text node would become a tree containing <html>, <head> and <body> elements.
43// Another example is that the programmatic equivalent of "a<head>b</head>c"
44// becomes "<html><head><head/><body>abc</body></html>".
45func Render(w io.Writer, n *Node) error {
46 if x, ok := w.(writer); ok {
47 return render(x, n)
48 }
49 buf := bufio.NewWriter(w)
50 if err := render(buf, n); err != nil {
51 return err
52 }
53 return buf.Flush()
54}
55
56// plaintextAbort is returned from render1 when a <plaintext> element
57// has been rendered. No more end tags should be rendered after that.
58var plaintextAbort = errors.New("html: internal error (plaintext abort)")
59
60func render(w writer, n *Node) error {
61 err := render1(w, n)
62 if err == plaintextAbort {
63 err = nil
64 }
65 return err
66}
67
68func render1(w writer, n *Node) error {
69 // Render non-element nodes; these are the easy cases.
70 switch n.Type {
71 case ErrorNode:
72 return errors.New("html: cannot render an ErrorNode node")
73 case TextNode:
74 return escape(w, n.Data)
75 case DocumentNode:
76 for c := n.FirstChild; c != nil; c = c.NextSibling {
77 if err := render1(w, c); err != nil {
78 return err
79 }
80 }
81 return nil
82 case ElementNode:
83 // No-op.
84 case CommentNode:
85 if _, err := w.WriteString("<!--"); err != nil {
86 return err
87 }
88 if _, err := w.WriteString(n.Data); err != nil {
89 return err
90 }
91 if _, err := w.WriteString("-->"); err != nil {
92 return err
93 }
94 return nil
95 case DoctypeNode:
96 if _, err := w.WriteString("<!DOCTYPE "); err != nil {
97 return err
98 }
99 if _, err := w.WriteString(n.Data); err != nil {
100 return err
101 }
102 if n.Attr != nil {
103 var p, s string
104 for _, a := range n.Attr {
105 switch a.Key {
106 case "public":
107 p = a.Val
108 case "system":
109 s = a.Val
110 }
111 }
112 if p != "" {
113 if _, err := w.WriteString(" PUBLIC "); err != nil {
114 return err
115 }
116 if err := writeQuoted(w, p); err != nil {
117 return err
118 }
119 if s != "" {
120 if err := w.WriteByte(' '); err != nil {
121 return err
122 }
123 if err := writeQuoted(w, s); err != nil {
124 return err
125 }
126 }
127 } else if s != "" {
128 if _, err := w.WriteString(" SYSTEM "); err != nil {
129 return err
130 }
131 if err := writeQuoted(w, s); err != nil {
132 return err
133 }
134 }
135 }
136 return w.WriteByte('>')
137 default:
138 return errors.New("html: unknown node type")
139 }
140
141 // Render the <xxx> opening tag.
142 if err := w.WriteByte('<'); err != nil {
143 return err
144 }
145 if _, err := w.WriteString(n.Data); err != nil {
146 return err
147 }
148 for _, a := range n.Attr {
149 if err := w.WriteByte(' '); err != nil {
150 return err
151 }
152 if a.Namespace != "" {
153 if _, err := w.WriteString(a.Namespace); err != nil {
154 return err
155 }
156 if err := w.WriteByte(':'); err != nil {
157 return err
158 }
159 }
160 if _, err := w.WriteString(a.Key); err != nil {
161 return err
162 }
163 if _, err := w.WriteString(`="`); err != nil {
164 return err
165 }
166 if err := escape(w, a.Val); err != nil {
167 return err
168 }
169 if err := w.WriteByte('"'); err != nil {
170 return err
171 }
172 }
173 if voidElements[n.Data] {
174 if n.FirstChild != nil {
175 return fmt.Errorf("html: void element <%s> has child nodes", n.Data)
176 }
177 _, err := w.WriteString("/>")
178 return err
179 }
180 if err := w.WriteByte('>'); err != nil {
181 return err
182 }
183
184 // Add initial newline where there is danger of a newline beging ignored.
185 if c := n.FirstChild; c != nil && c.Type == TextNode && strings.HasPrefix(c.Data, "\n") {
186 switch n.Data {
187 case "pre", "listing", "textarea":
188 if err := w.WriteByte('\n'); err != nil {
189 return err
190 }
191 }
192 }
193
194 // Render any child nodes.
195 switch n.Data {
196 case "iframe", "noembed", "noframes", "noscript", "plaintext", "script", "style", "xmp":
197 for c := n.FirstChild; c != nil; c = c.NextSibling {
198 if c.Type == TextNode {
199 if _, err := w.WriteString(c.Data); err != nil {
200 return err
201 }
202 } else {
203 if err := render1(w, c); err != nil {
204 return err
205 }
206 }
207 }
208 if n.Data == "plaintext" {
209 // Don't render anything else. <plaintext> must be the
210 // last element in the file, with no closing tag.
211 return plaintextAbort
212 }
213 default:
214 for c := n.FirstChild; c != nil; c = c.NextSibling {
215 if err := render1(w, c); err != nil {
216 return err
217 }
218 }
219 }
220
221 // Render the </xxx> closing tag.
222 if _, err := w.WriteString("</"); err != nil {
223 return err
224 }
225 if _, err := w.WriteString(n.Data); err != nil {
226 return err
227 }
228 return w.WriteByte('>')
229}
230
231// writeQuoted writes s to w surrounded by quotes. Normally it will use double
232// quotes, but if s contains a double quote, it will use single quotes.
233// It is used for writing the identifiers in a doctype declaration.
234// In valid HTML, they can't contain both types of quotes.
235func writeQuoted(w writer, s string) error {
236 var q byte = '"'
237 if strings.Contains(s, `"`) {
238 q = '\''
239 }
240 if err := w.WriteByte(q); err != nil {
241 return err
242 }
243 if _, err := w.WriteString(s); err != nil {
244 return err
245 }
246 if err := w.WriteByte(q); err != nil {
247 return err
248 }
249 return nil
250}
251
252// Section 12.1.2, "Elements", gives this list of void elements. Void elements
253// are those that can't have any contents.
254var voidElements = map[string]bool{
255 "area": true,
256 "base": true,
257 "br": true,
258 "col": true,
259 "command": true,
260 "embed": true,
261 "hr": true,
262 "img": true,
263 "input": true,
264 "keygen": true,
265 "link": true,
266 "meta": true,
267 "param": true,
268 "source": true,
269 "track": true,
270 "wbr": true,
271}
diff --git a/vendor/golang.org/x/net/html/token.go b/vendor/golang.org/x/net/html/token.go
new file mode 100644
index 0000000..893e272
--- /dev/null
+++ b/vendor/golang.org/x/net/html/token.go
@@ -0,0 +1,1219 @@
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
5package html
6
7import (
8 "bytes"
9 "errors"
10 "io"
11 "strconv"
12 "strings"
13
14 "golang.org/x/net/html/atom"
15)
16
17// A TokenType is the type of a Token.
18type TokenType uint32
19
20const (
21 // ErrorToken means that an error occurred during tokenization.
22 ErrorToken TokenType = iota
23 // TextToken means a text node.
24 TextToken
25 // A StartTagToken looks like <a>.
26 StartTagToken
27 // An EndTagToken looks like </a>.
28 EndTagToken
29 // A SelfClosingTagToken tag looks like <br/>.
30 SelfClosingTagToken
31 // A CommentToken looks like <!--x-->.
32 CommentToken
33 // A DoctypeToken looks like <!DOCTYPE x>
34 DoctypeToken
35)
36
37// ErrBufferExceeded means that the buffering limit was exceeded.
38var ErrBufferExceeded = errors.New("max buffer exceeded")
39
40// String returns a string representation of the TokenType.
41func (t TokenType) String() string {
42 switch t {
43 case ErrorToken:
44 return "Error"
45 case TextToken:
46 return "Text"
47 case StartTagToken:
48 return "StartTag"
49 case EndTagToken:
50 return "EndTag"
51 case SelfClosingTagToken:
52 return "SelfClosingTag"
53 case CommentToken:
54 return "Comment"
55 case DoctypeToken:
56 return "Doctype"
57 }
58 return "Invalid(" + strconv.Itoa(int(t)) + ")"
59}
60
61// An Attribute is an attribute namespace-key-value triple. Namespace is
62// non-empty for foreign attributes like xlink, Key is alphabetic (and hence
63// does not contain escapable characters like '&', '<' or '>'), and Val is
64// unescaped (it looks like "a<b" rather than "a&lt;b").
65//
66// Namespace is only used by the parser, not the tokenizer.
67type Attribute struct {
68 Namespace, Key, Val string
69}
70
71// A Token consists of a TokenType and some Data (tag name for start and end
72// tags, content for text, comments and doctypes). A tag Token may also contain
73// a slice of Attributes. Data is unescaped for all Tokens (it looks like "a<b"
74// rather than "a&lt;b"). For tag Tokens, DataAtom is the atom for Data, or
75// zero if Data is not a known tag name.
76type Token struct {
77 Type TokenType
78 DataAtom atom.Atom
79 Data string
80 Attr []Attribute
81}
82
83// tagString returns a string representation of a tag Token's Data and Attr.
84func (t Token) tagString() string {
85 if len(t.Attr) == 0 {
86 return t.Data
87 }
88 buf := bytes.NewBufferString(t.Data)
89 for _, a := range t.Attr {
90 buf.WriteByte(' ')
91 buf.WriteString(a.Key)
92 buf.WriteString(`="`)
93 escape(buf, a.Val)
94 buf.WriteByte('"')
95 }
96 return buf.String()
97}
98
99// String returns a string representation of the Token.
100func (t Token) String() string {
101 switch t.Type {
102 case ErrorToken:
103 return ""
104 case TextToken:
105 return EscapeString(t.Data)
106 case StartTagToken:
107 return "<" + t.tagString() + ">"
108 case EndTagToken:
109 return "</" + t.tagString() + ">"
110 case SelfClosingTagToken:
111 return "<" + t.tagString() + "/>"
112 case CommentToken:
113 return "<!--" + t.Data + "-->"
114 case DoctypeToken:
115 return "<!DOCTYPE " + t.Data + ">"
116 }
117 return "Invalid(" + strconv.Itoa(int(t.Type)) + ")"
118}
119
120// span is a range of bytes in a Tokenizer's buffer. The start is inclusive,
121// the end is exclusive.
122type span struct {
123 start, end int
124}
125
126// A Tokenizer returns a stream of HTML Tokens.
127type Tokenizer struct {
128 // r is the source of the HTML text.
129 r io.Reader
130 // tt is the TokenType of the current token.
131 tt TokenType
132 // err is the first error encountered during tokenization. It is possible
133 // for tt != Error && err != nil to hold: this means that Next returned a
134 // valid token but the subsequent Next call will return an error token.
135 // For example, if the HTML text input was just "plain", then the first
136 // Next call would set z.err to io.EOF but return a TextToken, and all
137 // subsequent Next calls would return an ErrorToken.
138 // err is never reset. Once it becomes non-nil, it stays non-nil.
139 err error
140 // readErr is the error returned by the io.Reader r. It is separate from
141 // err because it is valid for an io.Reader to return (n int, err1 error)
142 // such that n > 0 && err1 != nil, and callers should always process the
143 // n > 0 bytes before considering the error err1.
144 readErr error
145 // buf[raw.start:raw.end] holds the raw bytes of the current token.
146 // buf[raw.end:] is buffered input that will yield future tokens.
147 raw span
148 buf []byte
149 // maxBuf limits the data buffered in buf. A value of 0 means unlimited.
150 maxBuf int
151 // buf[data.start:data.end] holds the raw bytes of the current token's data:
152 // a text token's text, a tag token's tag name, etc.
153 data span
154 // pendingAttr is the attribute key and value currently being tokenized.
155 // When complete, pendingAttr is pushed onto attr. nAttrReturned is
156 // incremented on each call to TagAttr.
157 pendingAttr [2]span
158 attr [][2]span
159 nAttrReturned int
160 // rawTag is the "script" in "</script>" that closes the next token. If
161 // non-empty, the subsequent call to Next will return a raw or RCDATA text
162 // token: one that treats "<p>" as text instead of an element.
163 // rawTag's contents are lower-cased.
164 rawTag string
165 // textIsRaw is whether the current text token's data is not escaped.
166 textIsRaw bool
167 // convertNUL is whether NUL bytes in the current token's data should
168 // be converted into \ufffd replacement characters.
169 convertNUL bool
170 // allowCDATA is whether CDATA sections are allowed in the current context.
171 allowCDATA bool
172}
173
174// AllowCDATA sets whether or not the tokenizer recognizes <![CDATA[foo]]> as
175// the text "foo". The default value is false, which means to recognize it as
176// a bogus comment "<!-- [CDATA[foo]] -->" instead.
177//
178// Strictly speaking, an HTML5 compliant tokenizer should allow CDATA if and
179// only if tokenizing foreign content, such as MathML and SVG. However,
180// tracking foreign-contentness is difficult to do purely in the tokenizer,
181// as opposed to the parser, due to HTML integration points: an <svg> element
182// can contain a <foreignObject> that is foreign-to-SVG but not foreign-to-
183// HTML. For strict compliance with the HTML5 tokenization algorithm, it is the
184// responsibility of the user of a tokenizer to call AllowCDATA as appropriate.
185// In practice, if using the tokenizer without caring whether MathML or SVG
186// CDATA is text or comments, such as tokenizing HTML to find all the anchor
187// text, it is acceptable to ignore this responsibility.
188func (z *Tokenizer) AllowCDATA(allowCDATA bool) {
189 z.allowCDATA = allowCDATA
190}
191
192// NextIsNotRawText instructs the tokenizer that the next token should not be
193// considered as 'raw text'. Some elements, such as script and title elements,
194// normally require the next token after the opening tag to be 'raw text' that
195// has no child elements. For example, tokenizing "<title>a<b>c</b>d</title>"
196// yields a start tag token for "<title>", a text token for "a<b>c</b>d", and
197// an end tag token for "</title>". There are no distinct start tag or end tag
198// tokens for the "<b>" and "</b>".
199//
200// This tokenizer implementation will generally look for raw text at the right
201// times. Strictly speaking, an HTML5 compliant tokenizer should not look for
202// raw text if in foreign content: <title> generally needs raw text, but a
203// <title> inside an <svg> does not. Another example is that a <textarea>
204// generally needs raw text, but a <textarea> is not allowed as an immediate
205// child of a <select>; in normal parsing, a <textarea> implies </select>, but
206// one cannot close the implicit element when parsing a <select>'s InnerHTML.
207// Similarly to AllowCDATA, tracking the correct moment to override raw-text-
208// ness is difficult to do purely in the tokenizer, as opposed to the parser.
209// For strict compliance with the HTML5 tokenization algorithm, it is the
210// responsibility of the user of a tokenizer to call NextIsNotRawText as
211// appropriate. In practice, like AllowCDATA, it is acceptable to ignore this
212// responsibility for basic usage.
213//
214// Note that this 'raw text' concept is different from the one offered by the
215// Tokenizer.Raw method.
216func (z *Tokenizer) NextIsNotRawText() {
217 z.rawTag = ""
218}
219
220// Err returns the error associated with the most recent ErrorToken token.
221// This is typically io.EOF, meaning the end of tokenization.
222func (z *Tokenizer) Err() error {
223 if z.tt != ErrorToken {
224 return nil
225 }
226 return z.err
227}
228
229// readByte returns the next byte from the input stream, doing a buffered read
230// from z.r into z.buf if necessary. z.buf[z.raw.start:z.raw.end] remains a contiguous byte
231// slice that holds all the bytes read so far for the current token.
232// It sets z.err if the underlying reader returns an error.
233// Pre-condition: z.err == nil.
234func (z *Tokenizer) readByte() byte {
235 if z.raw.end >= len(z.buf) {
236 // Our buffer is exhausted and we have to read from z.r. Check if the
237 // previous read resulted in an error.
238 if z.readErr != nil {
239 z.err = z.readErr
240 return 0
241 }
242 // We copy z.buf[z.raw.start:z.raw.end] to the beginning of z.buf. If the length
243 // z.raw.end - z.raw.start is more than half the capacity of z.buf, then we
244 // allocate a new buffer before the copy.
245 c := cap(z.buf)
246 d := z.raw.end - z.raw.start
247 var buf1 []byte
248 if 2*d > c {
249 buf1 = make([]byte, d, 2*c)
250 } else {
251 buf1 = z.buf[:d]
252 }
253 copy(buf1, z.buf[z.raw.start:z.raw.end])
254 if x := z.raw.start; x != 0 {
255 // Adjust the data/attr spans to refer to the same contents after the copy.
256 z.data.start -= x
257 z.data.end -= x
258 z.pendingAttr[0].start -= x
259 z.pendingAttr[0].end -= x
260 z.pendingAttr[1].start -= x
261 z.pendingAttr[1].end -= x
262 for i := range z.attr {
263 z.attr[i][0].start -= x
264 z.attr[i][0].end -= x
265 z.attr[i][1].start -= x
266 z.attr[i][1].end -= x
267 }
268 }
269 z.raw.start, z.raw.end, z.buf = 0, d, buf1[:d]
270 // Now that we have copied the live bytes to the start of the buffer,
271 // we read from z.r into the remainder.
272 var n int
273 n, z.readErr = readAtLeastOneByte(z.r, buf1[d:cap(buf1)])
274 if n == 0 {
275 z.err = z.readErr
276 return 0
277 }
278 z.buf = buf1[:d+n]
279 }
280 x := z.buf[z.raw.end]
281 z.raw.end++
282 if z.maxBuf > 0 && z.raw.end-z.raw.start >= z.maxBuf {
283 z.err = ErrBufferExceeded
284 return 0
285 }
286 return x
287}
288
289// Buffered returns a slice containing data buffered but not yet tokenized.
290func (z *Tokenizer) Buffered() []byte {
291 return z.buf[z.raw.end:]
292}
293
294// readAtLeastOneByte wraps an io.Reader so that reading cannot return (0, nil).
295// It returns io.ErrNoProgress if the underlying r.Read method returns (0, nil)
296// too many times in succession.
297func readAtLeastOneByte(r io.Reader, b []byte) (int, error) {
298 for i := 0; i < 100; i++ {
299 n, err := r.Read(b)
300 if n != 0 || err != nil {
301 return n, err
302 }
303 }
304 return 0, io.ErrNoProgress
305}
306
307// skipWhiteSpace skips past any white space.
308func (z *Tokenizer) skipWhiteSpace() {
309 if z.err != nil {
310 return
311 }
312 for {
313 c := z.readByte()
314 if z.err != nil {
315 return
316 }
317 switch c {
318 case ' ', '\n', '\r', '\t', '\f':
319 // No-op.
320 default:
321 z.raw.end--
322 return
323 }
324 }
325}
326
327// readRawOrRCDATA reads until the next "</foo>", where "foo" is z.rawTag and
328// is typically something like "script" or "textarea".
329func (z *Tokenizer) readRawOrRCDATA() {
330 if z.rawTag == "script" {
331 z.readScript()
332 z.textIsRaw = true
333 z.rawTag = ""
334 return
335 }
336loop:
337 for {
338 c := z.readByte()
339 if z.err != nil {
340 break loop
341 }
342 if c != '<' {
343 continue loop
344 }
345 c = z.readByte()
346 if z.err != nil {
347 break loop
348 }
349 if c != '/' {
350 continue loop
351 }
352 if z.readRawEndTag() || z.err != nil {
353 break loop
354 }
355 }
356 z.data.end = z.raw.end
357 // A textarea's or title's RCDATA can contain escaped entities.
358 z.textIsRaw = z.rawTag != "textarea" && z.rawTag != "title"
359 z.rawTag = ""
360}
361
362// readRawEndTag attempts to read a tag like "</foo>", where "foo" is z.rawTag.
363// If it succeeds, it backs up the input position to reconsume the tag and
364// returns true. Otherwise it returns false. The opening "</" has already been
365// consumed.
366func (z *Tokenizer) readRawEndTag() bool {
367 for i := 0; i < len(z.rawTag); i++ {
368 c := z.readByte()
369 if z.err != nil {
370 return false
371 }
372 if c != z.rawTag[i] && c != z.rawTag[i]-('a'-'A') {
373 z.raw.end--
374 return false
375 }
376 }
377 c := z.readByte()
378 if z.err != nil {
379 return false
380 }
381 switch c {
382 case ' ', '\n', '\r', '\t', '\f', '/', '>':
383 // The 3 is 2 for the leading "</" plus 1 for the trailing character c.
384 z.raw.end -= 3 + len(z.rawTag)
385 return true
386 }
387 z.raw.end--
388 return false
389}
390
391// readScript reads until the next </script> tag, following the byzantine
392// rules for escaping/hiding the closing tag.
393func (z *Tokenizer) readScript() {
394 defer func() {
395 z.data.end = z.raw.end
396 }()
397 var c byte
398
399scriptData:
400 c = z.readByte()
401 if z.err != nil {
402 return
403 }
404 if c == '<' {
405 goto scriptDataLessThanSign
406 }
407 goto scriptData
408
409scriptDataLessThanSign:
410 c = z.readByte()
411 if z.err != nil {
412 return
413 }
414 switch c {
415 case '/':
416 goto scriptDataEndTagOpen
417 case '!':
418 goto scriptDataEscapeStart
419 }
420 z.raw.end--
421 goto scriptData
422
423scriptDataEndTagOpen:
424 if z.readRawEndTag() || z.err != nil {
425 return
426 }
427 goto scriptData
428
429scriptDataEscapeStart:
430 c = z.readByte()
431 if z.err != nil {
432 return
433 }
434 if c == '-' {
435 goto scriptDataEscapeStartDash
436 }
437 z.raw.end--
438 goto scriptData
439
440scriptDataEscapeStartDash:
441 c = z.readByte()
442 if z.err != nil {
443 return
444 }
445 if c == '-' {
446 goto scriptDataEscapedDashDash
447 }
448 z.raw.end--
449 goto scriptData
450
451scriptDataEscaped:
452 c = z.readByte()
453 if z.err != nil {
454 return
455 }
456 switch c {
457 case '-':
458 goto scriptDataEscapedDash
459 case '<':
460 goto scriptDataEscapedLessThanSign
461 }
462 goto scriptDataEscaped
463
464scriptDataEscapedDash:
465 c = z.readByte()
466 if z.err != nil {
467 return
468 }
469 switch c {
470 case '-':
471 goto scriptDataEscapedDashDash
472 case '<':
473 goto scriptDataEscapedLessThanSign
474 }
475 goto scriptDataEscaped
476
477scriptDataEscapedDashDash:
478 c = z.readByte()
479 if z.err != nil {
480 return
481 }
482 switch c {
483 case '-':
484 goto scriptDataEscapedDashDash
485 case '<':
486 goto scriptDataEscapedLessThanSign
487 case '>':
488 goto scriptData
489 }
490 goto scriptDataEscaped
491
492scriptDataEscapedLessThanSign:
493 c = z.readByte()
494 if z.err != nil {
495 return
496 }
497 if c == '/' {
498 goto scriptDataEscapedEndTagOpen
499 }
500 if 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' {
501 goto scriptDataDoubleEscapeStart
502 }
503 z.raw.end--
504 goto scriptData
505
506scriptDataEscapedEndTagOpen:
507 if z.readRawEndTag() || z.err != nil {
508 return
509 }
510 goto scriptDataEscaped
511
512scriptDataDoubleEscapeStart:
513 z.raw.end--
514 for i := 0; i < len("script"); i++ {
515 c = z.readByte()
516 if z.err != nil {
517 return
518 }
519 if c != "script"[i] && c != "SCRIPT"[i] {
520 z.raw.end--
521 goto scriptDataEscaped
522 }
523 }
524 c = z.readByte()
525 if z.err != nil {
526 return
527 }
528 switch c {
529 case ' ', '\n', '\r', '\t', '\f', '/', '>':
530 goto scriptDataDoubleEscaped
531 }
532 z.raw.end--
533 goto scriptDataEscaped
534
535scriptDataDoubleEscaped:
536 c = z.readByte()
537 if z.err != nil {
538 return
539 }
540 switch c {
541 case '-':
542 goto scriptDataDoubleEscapedDash
543 case '<':
544 goto scriptDataDoubleEscapedLessThanSign
545 }
546 goto scriptDataDoubleEscaped
547
548scriptDataDoubleEscapedDash:
549 c = z.readByte()
550 if z.err != nil {
551 return
552 }
553 switch c {
554 case '-':
555 goto scriptDataDoubleEscapedDashDash
556 case '<':
557 goto scriptDataDoubleEscapedLessThanSign
558 }
559 goto scriptDataDoubleEscaped
560
561scriptDataDoubleEscapedDashDash:
562 c = z.readByte()
563 if z.err != nil {
564 return
565 }
566 switch c {
567 case '-':
568 goto scriptDataDoubleEscapedDashDash
569 case '<':
570 goto scriptDataDoubleEscapedLessThanSign
571 case '>':
572 goto scriptData
573 }
574 goto scriptDataDoubleEscaped
575
576scriptDataDoubleEscapedLessThanSign:
577 c = z.readByte()
578 if z.err != nil {
579 return
580 }
581 if c == '/' {
582 goto scriptDataDoubleEscapeEnd
583 }
584 z.raw.end--
585 goto scriptDataDoubleEscaped
586
587scriptDataDoubleEscapeEnd:
588 if z.readRawEndTag() {
589 z.raw.end += len("</script>")
590 goto scriptDataEscaped
591 }
592 if z.err != nil {
593 return
594 }
595 goto scriptDataDoubleEscaped
596}
597
598// readComment reads the next comment token starting with "<!--". The opening
599// "<!--" has already been consumed.
600func (z *Tokenizer) readComment() {
601 z.data.start = z.raw.end
602 defer func() {
603 if z.data.end < z.data.start {
604 // It's a comment with no data, like <!-->.
605 z.data.end = z.data.start
606 }
607 }()
608 for dashCount := 2; ; {
609 c := z.readByte()
610 if z.err != nil {
611 // Ignore up to two dashes at EOF.
612 if dashCount > 2 {
613 dashCount = 2
614 }
615 z.data.end = z.raw.end - dashCount
616 return
617 }
618 switch c {
619 case '-':
620 dashCount++
621 continue
622 case '>':
623 if dashCount >= 2 {
624 z.data.end = z.raw.end - len("-->")
625 return
626 }
627 case '!':
628 if dashCount >= 2 {
629 c = z.readByte()
630 if z.err != nil {
631 z.data.end = z.raw.end
632 return
633 }
634 if c == '>' {
635 z.data.end = z.raw.end - len("--!>")
636 return
637 }
638 }
639 }
640 dashCount = 0
641 }
642}
643
644// readUntilCloseAngle reads until the next ">".
645func (z *Tokenizer) readUntilCloseAngle() {
646 z.data.start = z.raw.end
647 for {
648 c := z.readByte()
649 if z.err != nil {
650 z.data.end = z.raw.end
651 return
652 }
653 if c == '>' {
654 z.data.end = z.raw.end - len(">")
655 return
656 }
657 }
658}
659
660// readMarkupDeclaration reads the next token starting with "<!". It might be
661// a "<!--comment-->", a "<!DOCTYPE foo>", a "<![CDATA[section]]>" or
662// "<!a bogus comment". The opening "<!" has already been consumed.
663func (z *Tokenizer) readMarkupDeclaration() TokenType {
664 z.data.start = z.raw.end
665 var c [2]byte
666 for i := 0; i < 2; i++ {
667 c[i] = z.readByte()
668 if z.err != nil {
669 z.data.end = z.raw.end
670 return CommentToken
671 }
672 }
673 if c[0] == '-' && c[1] == '-' {
674 z.readComment()
675 return CommentToken
676 }
677 z.raw.end -= 2
678 if z.readDoctype() {
679 return DoctypeToken
680 }
681 if z.allowCDATA && z.readCDATA() {
682 z.convertNUL = true
683 return TextToken
684 }
685 // It's a bogus comment.
686 z.readUntilCloseAngle()
687 return CommentToken
688}
689
690// readDoctype attempts to read a doctype declaration and returns true if
691// successful. The opening "<!" has already been consumed.
692func (z *Tokenizer) readDoctype() bool {
693 const s = "DOCTYPE"
694 for i := 0; i < len(s); i++ {
695 c := z.readByte()
696 if z.err != nil {
697 z.data.end = z.raw.end
698 return false
699 }
700 if c != s[i] && c != s[i]+('a'-'A') {
701 // Back up to read the fragment of "DOCTYPE" again.
702 z.raw.end = z.data.start
703 return false
704 }
705 }
706 if z.skipWhiteSpace(); z.err != nil {
707 z.data.start = z.raw.end
708 z.data.end = z.raw.end
709 return true
710 }
711 z.readUntilCloseAngle()
712 return true
713}
714
715// readCDATA attempts to read a CDATA section and returns true if
716// successful. The opening "<!" has already been consumed.
717func (z *Tokenizer) readCDATA() bool {
718 const s = "[CDATA["
719 for i := 0; i < len(s); i++ {
720 c := z.readByte()
721 if z.err != nil {
722 z.data.end = z.raw.end
723 return false
724 }
725 if c != s[i] {
726 // Back up to read the fragment of "[CDATA[" again.
727 z.raw.end = z.data.start
728 return false
729 }
730 }
731 z.data.start = z.raw.end
732 brackets := 0
733 for {
734 c := z.readByte()
735 if z.err != nil {
736 z.data.end = z.raw.end
737 return true
738 }
739 switch c {
740 case ']':
741 brackets++
742 case '>':
743 if brackets >= 2 {
744 z.data.end = z.raw.end - len("]]>")
745 return true
746 }
747 brackets = 0
748 default:
749 brackets = 0
750 }
751 }
752}
753
754// startTagIn returns whether the start tag in z.buf[z.data.start:z.data.end]
755// case-insensitively matches any element of ss.
756func (z *Tokenizer) startTagIn(ss ...string) bool {
757loop:
758 for _, s := range ss {
759 if z.data.end-z.data.start != len(s) {
760 continue loop
761 }
762 for i := 0; i < len(s); i++ {
763 c := z.buf[z.data.start+i]
764 if 'A' <= c && c <= 'Z' {
765 c += 'a' - 'A'
766 }
767 if c != s[i] {
768 continue loop
769 }
770 }
771 return true
772 }
773 return false
774}
775
776// readStartTag reads the next start tag token. The opening "<a" has already
777// been consumed, where 'a' means anything in [A-Za-z].
778func (z *Tokenizer) readStartTag() TokenType {
779 z.readTag(true)
780 if z.err != nil {
781 return ErrorToken
782 }
783 // Several tags flag the tokenizer's next token as raw.
784 c, raw := z.buf[z.data.start], false
785 if 'A' <= c && c <= 'Z' {
786 c += 'a' - 'A'
787 }
788 switch c {
789 case 'i':
790 raw = z.startTagIn("iframe")
791 case 'n':
792 raw = z.startTagIn("noembed", "noframes", "noscript")
793 case 'p':
794 raw = z.startTagIn("plaintext")
795 case 's':
796 raw = z.startTagIn("script", "style")
797 case 't':
798 raw = z.startTagIn("textarea", "title")
799 case 'x':
800 raw = z.startTagIn("xmp")
801 }
802 if raw {
803 z.rawTag = strings.ToLower(string(z.buf[z.data.start:z.data.end]))
804 }
805 // Look for a self-closing token like "<br/>".
806 if z.err == nil && z.buf[z.raw.end-2] == '/' {
807 return SelfClosingTagToken
808 }
809 return StartTagToken
810}
811
812// readTag reads the next tag token and its attributes. If saveAttr, those
813// attributes are saved in z.attr, otherwise z.attr is set to an empty slice.
814// The opening "<a" or "</a" has already been consumed, where 'a' means anything
815// in [A-Za-z].
816func (z *Tokenizer) readTag(saveAttr bool) {
817 z.attr = z.attr[:0]
818 z.nAttrReturned = 0
819 // Read the tag name and attribute key/value pairs.
820 z.readTagName()
821 if z.skipWhiteSpace(); z.err != nil {
822 return
823 }
824 for {
825 c := z.readByte()
826 if z.err != nil || c == '>' {
827 break
828 }
829 z.raw.end--
830 z.readTagAttrKey()
831 z.readTagAttrVal()
832 // Save pendingAttr if saveAttr and that attribute has a non-empty key.
833 if saveAttr && z.pendingAttr[0].start != z.pendingAttr[0].end {
834 z.attr = append(z.attr, z.pendingAttr)
835 }
836 if z.skipWhiteSpace(); z.err != nil {
837 break
838 }
839 }
840}
841
842// readTagName sets z.data to the "div" in "<div k=v>". The reader (z.raw.end)
843// is positioned such that the first byte of the tag name (the "d" in "<div")
844// has already been consumed.
845func (z *Tokenizer) readTagName() {
846 z.data.start = z.raw.end - 1
847 for {
848 c := z.readByte()
849 if z.err != nil {
850 z.data.end = z.raw.end
851 return
852 }
853 switch c {
854 case ' ', '\n', '\r', '\t', '\f':
855 z.data.end = z.raw.end - 1
856 return
857 case '/', '>':
858 z.raw.end--
859 z.data.end = z.raw.end
860 return
861 }
862 }
863}
864
865// readTagAttrKey sets z.pendingAttr[0] to the "k" in "<div k=v>".
866// Precondition: z.err == nil.
867func (z *Tokenizer) readTagAttrKey() {
868 z.pendingAttr[0].start = z.raw.end
869 for {
870 c := z.readByte()
871 if z.err != nil {
872 z.pendingAttr[0].end = z.raw.end
873 return
874 }
875 switch c {
876 case ' ', '\n', '\r', '\t', '\f', '/':
877 z.pendingAttr[0].end = z.raw.end - 1
878 return
879 case '=', '>':
880 z.raw.end--
881 z.pendingAttr[0].end = z.raw.end
882 return
883 }
884 }
885}
886
887// readTagAttrVal sets z.pendingAttr[1] to the "v" in "<div k=v>".
888func (z *Tokenizer) readTagAttrVal() {
889 z.pendingAttr[1].start = z.raw.end
890 z.pendingAttr[1].end = z.raw.end
891 if z.skipWhiteSpace(); z.err != nil {
892 return
893 }
894 c := z.readByte()
895 if z.err != nil {
896 return
897 }
898 if c != '=' {
899 z.raw.end--
900 return
901 }
902 if z.skipWhiteSpace(); z.err != nil {
903 return
904 }
905 quote := z.readByte()
906 if z.err != nil {
907 return
908 }
909 switch quote {
910 case '>':
911 z.raw.end--
912 return
913
914 case '\'', '"':
915 z.pendingAttr[1].start = z.raw.end
916 for {
917 c := z.readByte()
918 if z.err != nil {
919 z.pendingAttr[1].end = z.raw.end
920 return
921 }
922 if c == quote {
923 z.pendingAttr[1].end = z.raw.end - 1
924 return
925 }
926 }
927
928 default:
929 z.pendingAttr[1].start = z.raw.end - 1
930 for {
931 c := z.readByte()
932 if z.err != nil {
933 z.pendingAttr[1].end = z.raw.end
934 return
935 }
936 switch c {
937 case ' ', '\n', '\r', '\t', '\f':
938 z.pendingAttr[1].end = z.raw.end - 1
939 return
940 case '>':
941 z.raw.end--
942 z.pendingAttr[1].end = z.raw.end
943 return
944 }
945 }
946 }
947}
948
949// Next scans the next token and returns its type.
950func (z *Tokenizer) Next() TokenType {
951 z.raw.start = z.raw.end
952 z.data.start = z.raw.end
953 z.data.end = z.raw.end
954 if z.err != nil {
955 z.tt = ErrorToken
956 return z.tt
957 }
958 if z.rawTag != "" {
959 if z.rawTag == "plaintext" {
960 // Read everything up to EOF.
961 for z.err == nil {
962 z.readByte()
963 }
964 z.data.end = z.raw.end
965 z.textIsRaw = true
966 } else {
967 z.readRawOrRCDATA()
968 }
969 if z.data.end > z.data.start {
970 z.tt = TextToken
971 z.convertNUL = true
972 return z.tt
973 }
974 }
975 z.textIsRaw = false
976 z.convertNUL = false
977
978loop:
979 for {
980 c := z.readByte()
981 if z.err != nil {
982 break loop
983 }
984 if c != '<' {
985 continue loop
986 }
987
988 // Check if the '<' we have just read is part of a tag, comment
989 // or doctype. If not, it's part of the accumulated text token.
990 c = z.readByte()
991 if z.err != nil {
992 break loop
993 }
994 var tokenType TokenType
995 switch {
996 case 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z':
997 tokenType = StartTagToken
998 case c == '/':
999 tokenType = EndTagToken
1000 case c == '!' || c == '?':
1001 // We use CommentToken to mean any of "<!--actual comments-->",
1002 // "<!DOCTYPE declarations>" and "<?xml processing instructions?>".
1003 tokenType = CommentToken
1004 default:
1005 // Reconsume the current character.
1006 z.raw.end--
1007 continue
1008 }
1009
1010 // We have a non-text token, but we might have accumulated some text
1011 // before that. If so, we return the text first, and return the non-
1012 // text token on the subsequent call to Next.
1013 if x := z.raw.end - len("<a"); z.raw.start < x {
1014 z.raw.end = x
1015 z.data.end = x
1016 z.tt = TextToken
1017 return z.tt
1018 }
1019 switch tokenType {
1020 case StartTagToken:
1021 z.tt = z.readStartTag()
1022 return z.tt
1023 case EndTagToken:
1024 c = z.readByte()
1025 if z.err != nil {
1026 break loop
1027 }
1028 if c == '>' {
1029 // "</>" does not generate a token at all. Generate an empty comment
1030 // to allow passthrough clients to pick up the data using Raw.
1031 // Reset the tokenizer state and start again.
1032 z.tt = CommentToken
1033 return z.tt
1034 }
1035 if 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' {
1036 z.readTag(false)
1037 if z.err != nil {
1038 z.tt = ErrorToken
1039 } else {
1040 z.tt = EndTagToken
1041 }
1042 return z.tt
1043 }
1044 z.raw.end--
1045 z.readUntilCloseAngle()
1046 z.tt = CommentToken
1047 return z.tt
1048 case CommentToken:
1049 if c == '!' {
1050 z.tt = z.readMarkupDeclaration()
1051 return z.tt
1052 }
1053 z.raw.end--
1054 z.readUntilCloseAngle()
1055 z.tt = CommentToken
1056 return z.tt
1057 }
1058 }
1059 if z.raw.start < z.raw.end {
1060 z.data.end = z.raw.end
1061 z.tt = TextToken
1062 return z.tt
1063 }
1064 z.tt = ErrorToken
1065 return z.tt
1066}
1067
1068// Raw returns the unmodified text of the current token. Calling Next, Token,
1069// Text, TagName or TagAttr may change the contents of the returned slice.
1070func (z *Tokenizer) Raw() []byte {
1071 return z.buf[z.raw.start:z.raw.end]
1072}
1073
1074// convertNewlines converts "\r" and "\r\n" in s to "\n".
1075// The conversion happens in place, but the resulting slice may be shorter.
1076func convertNewlines(s []byte) []byte {
1077 for i, c := range s {
1078 if c != '\r' {
1079 continue
1080 }
1081
1082 src := i + 1
1083 if src >= len(s) || s[src] != '\n' {
1084 s[i] = '\n'
1085 continue
1086 }
1087
1088 dst := i
1089 for src < len(s) {
1090 if s[src] == '\r' {
1091 if src+1 < len(s) && s[src+1] == '\n' {
1092 src++
1093 }
1094 s[dst] = '\n'
1095 } else {
1096 s[dst] = s[src]
1097 }
1098 src++
1099 dst++
1100 }
1101 return s[:dst]
1102 }
1103 return s
1104}
1105
1106var (
1107 nul = []byte("\x00")
1108 replacement = []byte("\ufffd")
1109)
1110
1111// Text returns the unescaped text of a text, comment or doctype token. The
1112// contents of the returned slice may change on the next call to Next.
1113func (z *Tokenizer) Text() []byte {
1114 switch z.tt {
1115 case TextToken, CommentToken, DoctypeToken:
1116 s := z.buf[z.data.start:z.data.end]
1117 z.data.start = z.raw.end
1118 z.data.end = z.raw.end
1119 s = convertNewlines(s)
1120 if (z.convertNUL || z.tt == CommentToken) && bytes.Contains(s, nul) {
1121 s = bytes.Replace(s, nul, replacement, -1)
1122 }
1123 if !z.textIsRaw {
1124 s = unescape(s, false)
1125 }
1126 return s
1127 }
1128 return nil
1129}
1130
1131// TagName returns the lower-cased name of a tag token (the `img` out of
1132// `<IMG SRC="foo">`) and whether the tag has attributes.
1133// The contents of the returned slice may change on the next call to Next.
1134func (z *Tokenizer) TagName() (name []byte, hasAttr bool) {
1135 if z.data.start < z.data.end {
1136 switch z.tt {
1137 case StartTagToken, EndTagToken, SelfClosingTagToken:
1138 s := z.buf[z.data.start:z.data.end]
1139 z.data.start = z.raw.end
1140 z.data.end = z.raw.end
1141 return lower(s), z.nAttrReturned < len(z.attr)
1142 }
1143 }
1144 return nil, false
1145}
1146
1147// TagAttr returns the lower-cased key and unescaped value of the next unparsed
1148// attribute for the current tag token and whether there are more attributes.
1149// The contents of the returned slices may change on the next call to Next.
1150func (z *Tokenizer) TagAttr() (key, val []byte, moreAttr bool) {
1151 if z.nAttrReturned < len(z.attr) {
1152 switch z.tt {
1153 case StartTagToken, SelfClosingTagToken:
1154 x := z.attr[z.nAttrReturned]
1155 z.nAttrReturned++
1156 key = z.buf[x[0].start:x[0].end]
1157 val = z.buf[x[1].start:x[1].end]
1158 return lower(key), unescape(convertNewlines(val), true), z.nAttrReturned < len(z.attr)
1159 }
1160 }
1161 return nil, nil, false
1162}
1163
1164// Token returns the next Token. The result's Data and Attr values remain valid
1165// after subsequent Next calls.
1166func (z *Tokenizer) Token() Token {
1167 t := Token{Type: z.tt}
1168 switch z.tt {
1169 case TextToken, CommentToken, DoctypeToken:
1170 t.Data = string(z.Text())
1171 case StartTagToken, SelfClosingTagToken, EndTagToken:
1172 name, moreAttr := z.TagName()
1173 for moreAttr {
1174 var key, val []byte
1175 key, val, moreAttr = z.TagAttr()
1176 t.Attr = append(t.Attr, Attribute{"", atom.String(key), string(val)})
1177 }
1178 if a := atom.Lookup(name); a != 0 {
1179 t.DataAtom, t.Data = a, a.String()
1180 } else {
1181 t.DataAtom, t.Data = 0, string(name)
1182 }
1183 }
1184 return t
1185}
1186
1187// SetMaxBuf sets a limit on the amount of data buffered during tokenization.
1188// A value of 0 means unlimited.
1189func (z *Tokenizer) SetMaxBuf(n int) {
1190 z.maxBuf = n
1191}
1192
1193// NewTokenizer returns a new HTML Tokenizer for the given Reader.
1194// The input is assumed to be UTF-8 encoded.
1195func NewTokenizer(r io.Reader) *Tokenizer {
1196 return NewTokenizerFragment(r, "")
1197}
1198
1199// NewTokenizerFragment returns a new HTML Tokenizer for the given Reader, for
1200// tokenizing an existing element's InnerHTML fragment. contextTag is that
1201// element's tag, such as "div" or "iframe".
1202//
1203// For example, how the InnerHTML "a<b" is tokenized depends on whether it is
1204// for a <p> tag or a <script> tag.
1205//
1206// The input is assumed to be UTF-8 encoded.
1207func NewTokenizerFragment(r io.Reader, contextTag string) *Tokenizer {
1208 z := &Tokenizer{
1209 r: r,
1210 buf: make([]byte, 0, 4096),
1211 }
1212 if contextTag != "" {
1213 switch s := strings.ToLower(contextTag); s {
1214 case "iframe", "noembed", "noframes", "noscript", "plaintext", "script", "style", "title", "textarea", "xmp":
1215 z.rawTag = s
1216 }
1217 }
1218 return z
1219}