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