main
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)