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