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