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