main
Raw Download raw file
  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	packetTypeMarker                                   packetType = 10
315	packetTypeLiteralData                              packetType = 11
316	packetTypeTrust                                    packetType = 12
317	packetTypeUserId                                   packetType = 13
318	packetTypePublicSubkey                             packetType = 14
319	packetTypeUserAttribute                            packetType = 17
320	packetTypeSymmetricallyEncryptedIntegrityProtected packetType = 18
321	packetTypeAEADEncrypted                            packetType = 20
322	packetPadding                                      packetType = 21
323)
324
325// EncryptedDataPacket holds encrypted data. It is currently implemented by
326// SymmetricallyEncrypted and AEADEncrypted.
327type EncryptedDataPacket interface {
328	Decrypt(CipherFunction, []byte) (io.ReadCloser, error)
329}
330
331// Read reads a single OpenPGP packet from the given io.Reader. If there is an
332// error parsing a packet, the whole packet is consumed from the input.
333func Read(r io.Reader) (p Packet, err error) {
334	tag, len, contents, err := readHeader(r)
335	if err != nil {
336		return
337	}
338
339	switch tag {
340	case packetTypeEncryptedKey:
341		p = new(EncryptedKey)
342	case packetTypeSignature:
343		p = new(Signature)
344	case packetTypeSymmetricKeyEncrypted:
345		p = new(SymmetricKeyEncrypted)
346	case packetTypeOnePassSignature:
347		p = new(OnePassSignature)
348	case packetTypePrivateKey, packetTypePrivateSubkey:
349		pk := new(PrivateKey)
350		if tag == packetTypePrivateSubkey {
351			pk.IsSubkey = true
352		}
353		p = pk
354	case packetTypePublicKey, packetTypePublicSubkey:
355		isSubkey := tag == packetTypePublicSubkey
356		p = &PublicKey{IsSubkey: isSubkey}
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 packetTypeSymmetricallyEncryptedIntegrityProtected:
368		se := new(SymmetricallyEncrypted)
369		se.IntegrityProtected = true
370		p = se
371	case packetTypeAEADEncrypted:
372		p = new(AEADEncrypted)
373	case packetPadding:
374		p = Padding(len)
375	case packetTypeMarker:
376		p = new(Marker)
377	case packetTypeTrust:
378		// Not implemented, just consume
379		err = errors.UnknownPacketTypeError(tag)
380	default:
381		// Packet Tags from 0 to 39 are critical.
382		// Packet Tags from 40 to 63 are non-critical.
383		if tag < 40 {
384			err = errors.CriticalUnknownPacketTypeError(tag)
385		} else {
386			err = errors.UnknownPacketTypeError(tag)
387		}
388	}
389	if p != nil {
390		err = p.parse(contents)
391	}
392	if err != nil {
393		consumeAll(contents)
394	}
395	return
396}
397
398// ReadWithCheck reads a single OpenPGP message packet from the given io.Reader. If there is an
399// error parsing a packet, the whole packet is consumed from the input.
400// ReadWithCheck additionally checks if the OpenPGP message packet sequence adheres
401// to the packet composition rules in rfc4880, if not throws an error.
402func ReadWithCheck(r io.Reader, sequence *SequenceVerifier) (p Packet, msgErr error, err error) {
403	tag, len, contents, err := readHeader(r)
404	if err != nil {
405		return
406	}
407	switch tag {
408	case packetTypeEncryptedKey:
409		msgErr = sequence.Next(ESKSymbol)
410		p = new(EncryptedKey)
411	case packetTypeSignature:
412		msgErr = sequence.Next(SigSymbol)
413		p = new(Signature)
414	case packetTypeSymmetricKeyEncrypted:
415		msgErr = sequence.Next(ESKSymbol)
416		p = new(SymmetricKeyEncrypted)
417	case packetTypeOnePassSignature:
418		msgErr = sequence.Next(OPSSymbol)
419		p = new(OnePassSignature)
420	case packetTypeCompressed:
421		msgErr = sequence.Next(CompSymbol)
422		p = new(Compressed)
423	case packetTypeSymmetricallyEncrypted:
424		msgErr = sequence.Next(EncSymbol)
425		p = new(SymmetricallyEncrypted)
426	case packetTypeLiteralData:
427		msgErr = sequence.Next(LDSymbol)
428		p = new(LiteralData)
429	case packetTypeSymmetricallyEncryptedIntegrityProtected:
430		msgErr = sequence.Next(EncSymbol)
431		se := new(SymmetricallyEncrypted)
432		se.IntegrityProtected = true
433		p = se
434	case packetTypeAEADEncrypted:
435		msgErr = sequence.Next(EncSymbol)
436		p = new(AEADEncrypted)
437	case packetPadding:
438		p = Padding(len)
439	case packetTypeMarker:
440		p = new(Marker)
441	case packetTypeTrust:
442		// Not implemented, just consume
443		err = errors.UnknownPacketTypeError(tag)
444	case packetTypePrivateKey,
445		packetTypePrivateSubkey,
446		packetTypePublicKey,
447		packetTypePublicSubkey,
448		packetTypeUserId,
449		packetTypeUserAttribute:
450		msgErr = sequence.Next(UnknownSymbol)
451		consumeAll(contents)
452	default:
453		// Packet Tags from 0 to 39 are critical.
454		// Packet Tags from 40 to 63 are non-critical.
455		if tag < 40 {
456			err = errors.CriticalUnknownPacketTypeError(tag)
457		} else {
458			err = errors.UnknownPacketTypeError(tag)
459		}
460	}
461	if p != nil {
462		err = p.parse(contents)
463	}
464	if err != nil {
465		consumeAll(contents)
466	}
467	return
468}
469
470// SignatureType represents the different semantic meanings of an OpenPGP
471// signature. See RFC 4880, section 5.2.1.
472type SignatureType uint8
473
474const (
475	SigTypeBinary                  SignatureType = 0x00
476	SigTypeText                    SignatureType = 0x01
477	SigTypeGenericCert             SignatureType = 0x10
478	SigTypePersonaCert             SignatureType = 0x11
479	SigTypeCasualCert              SignatureType = 0x12
480	SigTypePositiveCert            SignatureType = 0x13
481	SigTypeSubkeyBinding           SignatureType = 0x18
482	SigTypePrimaryKeyBinding       SignatureType = 0x19
483	SigTypeDirectSignature         SignatureType = 0x1F
484	SigTypeKeyRevocation           SignatureType = 0x20
485	SigTypeSubkeyRevocation        SignatureType = 0x28
486	SigTypeCertificationRevocation SignatureType = 0x30
487)
488
489// PublicKeyAlgorithm represents the different public key system specified for
490// OpenPGP. See
491// http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-12
492type PublicKeyAlgorithm uint8
493
494const (
495	PubKeyAlgoRSA     PublicKeyAlgorithm = 1
496	PubKeyAlgoElGamal PublicKeyAlgorithm = 16
497	PubKeyAlgoDSA     PublicKeyAlgorithm = 17
498	// RFC 6637, Section 5.
499	PubKeyAlgoECDH  PublicKeyAlgorithm = 18
500	PubKeyAlgoECDSA PublicKeyAlgorithm = 19
501	// https://www.ietf.org/archive/id/draft-koch-eddsa-for-openpgp-04.txt
502	PubKeyAlgoEdDSA PublicKeyAlgorithm = 22
503	// https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh
504	PubKeyAlgoX25519  PublicKeyAlgorithm = 25
505	PubKeyAlgoX448    PublicKeyAlgorithm = 26
506	PubKeyAlgoEd25519 PublicKeyAlgorithm = 27
507	PubKeyAlgoEd448   PublicKeyAlgorithm = 28
508
509	// Deprecated in RFC 4880, Section 13.5. Use key flags instead.
510	PubKeyAlgoRSAEncryptOnly PublicKeyAlgorithm = 2
511	PubKeyAlgoRSASignOnly    PublicKeyAlgorithm = 3
512)
513
514// CanEncrypt returns true if it's possible to encrypt a message to a public
515// key of the given type.
516func (pka PublicKeyAlgorithm) CanEncrypt() bool {
517	switch pka {
518	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoElGamal, PubKeyAlgoECDH, PubKeyAlgoX25519, PubKeyAlgoX448:
519		return true
520	}
521	return false
522}
523
524// CanSign returns true if it's possible for a public key of the given type to
525// sign a message.
526func (pka PublicKeyAlgorithm) CanSign() bool {
527	switch pka {
528	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoDSA, PubKeyAlgoECDSA, PubKeyAlgoEdDSA, PubKeyAlgoEd25519, PubKeyAlgoEd448:
529		return true
530	}
531	return false
532}
533
534// CipherFunction represents the different block ciphers specified for OpenPGP. See
535// http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-13
536type CipherFunction algorithm.CipherFunction
537
538const (
539	Cipher3DES   CipherFunction = 2
540	CipherCAST5  CipherFunction = 3
541	CipherAES128 CipherFunction = 7
542	CipherAES192 CipherFunction = 8
543	CipherAES256 CipherFunction = 9
544)
545
546// KeySize returns the key size, in bytes, of cipher.
547func (cipher CipherFunction) KeySize() int {
548	return algorithm.CipherFunction(cipher).KeySize()
549}
550
551// IsSupported returns true if the cipher is supported from the library
552func (cipher CipherFunction) IsSupported() bool {
553	return algorithm.CipherFunction(cipher).KeySize() > 0
554}
555
556// blockSize returns the block size, in bytes, of cipher.
557func (cipher CipherFunction) blockSize() int {
558	return algorithm.CipherFunction(cipher).BlockSize()
559}
560
561// new returns a fresh instance of the given cipher.
562func (cipher CipherFunction) new(key []byte) (block cipher.Block) {
563	return algorithm.CipherFunction(cipher).New(key)
564}
565
566// padToKeySize left-pads a MPI with zeroes to match the length of the
567// specified RSA public.
568func padToKeySize(pub *rsa.PublicKey, b []byte) []byte {
569	k := (pub.N.BitLen() + 7) / 8
570	if len(b) >= k {
571		return b
572	}
573	bb := make([]byte, k)
574	copy(bb[len(bb)-len(b):], b)
575	return bb
576}
577
578// CompressionAlgo Represents the different compression algorithms
579// supported by OpenPGP (except for BZIP2, which is not currently
580// supported). See Section 9.3 of RFC 4880.
581type CompressionAlgo uint8
582
583const (
584	CompressionNone CompressionAlgo = 0
585	CompressionZIP  CompressionAlgo = 1
586	CompressionZLIB CompressionAlgo = 2
587)
588
589// AEADMode represents the different Authenticated Encryption with Associated
590// Data specified for OpenPGP.
591// See https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#section-9.6
592type AEADMode algorithm.AEADMode
593
594const (
595	AEADModeEAX AEADMode = 1
596	AEADModeOCB AEADMode = 2
597	AEADModeGCM AEADMode = 3
598)
599
600func (mode AEADMode) IvLength() int {
601	return algorithm.AEADMode(mode).NonceLength()
602}
603
604func (mode AEADMode) TagLength() int {
605	return algorithm.AEADMode(mode).TagLength()
606}
607
608// IsSupported returns true if the aead mode is supported from the library
609func (mode AEADMode) IsSupported() bool {
610	return algorithm.AEADMode(mode).TagLength() > 0
611}
612
613// new returns a fresh instance of the given mode.
614func (mode AEADMode) new(block cipher.Block) cipher.AEAD {
615	return algorithm.AEADMode(mode).New(block)
616}
617
618// ReasonForRevocation represents a revocation reason code as per RFC4880
619// section 5.2.3.23.
620type ReasonForRevocation uint8
621
622const (
623	NoReason       ReasonForRevocation = 0
624	KeySuperseded  ReasonForRevocation = 1
625	KeyCompromised ReasonForRevocation = 2
626	KeyRetired     ReasonForRevocation = 3
627	UserIDNotValid ReasonForRevocation = 32
628	Unknown        ReasonForRevocation = 200
629)
630
631func NewReasonForRevocation(value byte) ReasonForRevocation {
632	if value < 4 || value == 32 {
633		return ReasonForRevocation(value)
634	}
635	return Unknown
636}
637
638// Curve is a mapping to supported ECC curves for key generation.
639// See https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-06.html#name-curve-specific-wire-formats
640type Curve string
641
642const (
643	Curve25519         Curve = "Curve25519"
644	Curve448           Curve = "Curve448"
645	CurveNistP256      Curve = "P256"
646	CurveNistP384      Curve = "P384"
647	CurveNistP521      Curve = "P521"
648	CurveSecP256k1     Curve = "SecP256k1"
649	CurveBrainpoolP256 Curve = "BrainpoolP256"
650	CurveBrainpoolP384 Curve = "BrainpoolP384"
651	CurveBrainpoolP512 Curve = "BrainpoolP512"
652)
653
654// TrustLevel represents a trust level per RFC4880 5.2.3.13
655type TrustLevel uint8
656
657// TrustAmount represents a trust amount per RFC4880 5.2.3.13
658type TrustAmount uint8
659
660const (
661	// versionSize is the length in bytes of the version value.
662	versionSize = 1
663	// algorithmSize is the length in bytes of the key algorithm value.
664	algorithmSize = 1
665	// keyVersionSize is the length in bytes of the key version value
666	keyVersionSize = 1
667	// keyIdSize is the length in bytes of the key identifier value.
668	keyIdSize = 8
669	// timestampSize is the length in bytes of encoded timestamps.
670	timestampSize = 4
671	// fingerprintSizeV6 is the length in bytes of the key fingerprint in v6.
672	fingerprintSizeV6 = 32
673	// fingerprintSize is the length in bytes of the key fingerprint.
674	fingerprintSize = 20
675)