...

Source file src/github.com/ProtonMail/go-crypto/openpgp/packet/packet.go

Documentation: github.com/ProtonMail/go-crypto/openpgp/packet

     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 "github.com/ProtonMail/go-crypto/openpgp/packet"
     8  
     9  import (
    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.
    21  func 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.
    30  func 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.
    65  type partialLengthReader struct {
    66  	r         io.Reader
    67  	remaining int64
    68  	isPartial bool
    69  }
    70  
    71  func (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.
    97  type partialLengthWriter struct {
    98  	w          io.WriteCloser
    99  	buf        bytes.Buffer
   100  	lengthByte [1]byte
   101  }
   102  
   103  func (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  
   129  func (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.
   144  type spanReader struct {
   145  	r io.Reader
   146  	n int64
   147  }
   148  
   149  func (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.
   166  func 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.
   219  func 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.
   229  func 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.
   238  func 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.
   266  func 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.
   277  type 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.
   283  func 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
   302  type packetType uint8
   303  
   304  const (
   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  	packetTypeSymmetricallyEncryptedIntegrityProtected packetType = 18
   319  	packetTypeAEADEncrypted                            packetType = 20
   320  )
   321  
   322  // EncryptedDataPacket holds encrypted data. It is currently implemented by
   323  // SymmetricallyEncrypted and AEADEncrypted.
   324  type 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.
   330  func 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  		p = new(SymmetricallyEncrypted)
   358  	case packetTypeLiteralData:
   359  		p = new(LiteralData)
   360  	case packetTypeUserId:
   361  		p = new(UserId)
   362  	case packetTypeUserAttribute:
   363  		p = new(UserAttribute)
   364  	case packetTypeSymmetricallyEncryptedIntegrityProtected:
   365  		se := new(SymmetricallyEncrypted)
   366  		se.IntegrityProtected = 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.
   384  type SignatureType uint8
   385  
   386  const (
   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
   404  type PublicKeyAlgorithm uint8
   405  
   406  const (
   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.
   423  func (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.
   433  func (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
   443  type CipherFunction algorithm.CipherFunction
   444  
   445  const (
   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.
   454  func (cipher CipherFunction) KeySize() int {
   455  	return algorithm.CipherFunction(cipher).KeySize()
   456  }
   457  
   458  // IsSupported returns true if the cipher is supported from the library
   459  func (cipher CipherFunction) IsSupported() bool {
   460  	return algorithm.CipherFunction(cipher).KeySize() > 0
   461  }
   462  
   463  // blockSize returns the block size, in bytes, of cipher.
   464  func (cipher CipherFunction) blockSize() int {
   465  	return algorithm.CipherFunction(cipher).BlockSize()
   466  }
   467  
   468  // new returns a fresh instance of the given cipher.
   469  func (cipher CipherFunction) new(key []byte) (block cipher.Block) {
   470  	return algorithm.CipherFunction(cipher).New(key)
   471  }
   472  
   473  // padToKeySize left-pads a MPI with zeroes to match the length of the
   474  // specified RSA public.
   475  func padToKeySize(pub *rsa.PublicKey, b []byte) []byte {
   476  	k := (pub.N.BitLen() + 7) / 8
   477  	if len(b) >= k {
   478  		return b
   479  	}
   480  	bb := make([]byte, k)
   481  	copy(bb[len(bb)-len(b):], b)
   482  	return bb
   483  }
   484  
   485  // CompressionAlgo Represents the different compression algorithms
   486  // supported by OpenPGP (except for BZIP2, which is not currently
   487  // supported). See Section 9.3 of RFC 4880.
   488  type CompressionAlgo uint8
   489  
   490  const (
   491  	CompressionNone CompressionAlgo = 0
   492  	CompressionZIP  CompressionAlgo = 1
   493  	CompressionZLIB CompressionAlgo = 2
   494  )
   495  
   496  // AEADMode represents the different Authenticated Encryption with Associated
   497  // Data specified for OpenPGP.
   498  // See https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#section-9.6
   499  type AEADMode algorithm.AEADMode
   500  
   501  const (
   502  	AEADModeEAX AEADMode = 1
   503  	AEADModeOCB AEADMode = 2
   504  	AEADModeGCM AEADMode = 3
   505  )
   506  
   507  func (mode AEADMode) IvLength() int {
   508  	return algorithm.AEADMode(mode).NonceLength()
   509  }
   510  
   511  func (mode AEADMode) TagLength() int {
   512  	return algorithm.AEADMode(mode).TagLength()
   513  }
   514  
   515  // new returns a fresh instance of the given mode.
   516  func (mode AEADMode) new(block cipher.Block) cipher.AEAD {
   517  	return algorithm.AEADMode(mode).New(block)
   518  }
   519  
   520  // ReasonForRevocation represents a revocation reason code as per RFC4880
   521  // section 5.2.3.23.
   522  type ReasonForRevocation uint8
   523  
   524  const (
   525  	NoReason       ReasonForRevocation = 0
   526  	KeySuperseded  ReasonForRevocation = 1
   527  	KeyCompromised ReasonForRevocation = 2
   528  	KeyRetired     ReasonForRevocation = 3
   529  )
   530  
   531  // Curve is a mapping to supported ECC curves for key generation.
   532  // See https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-06.html#name-curve-specific-wire-formats
   533  type Curve string
   534  
   535  const (
   536  	Curve25519         Curve = "Curve25519"
   537  	Curve448           Curve = "Curve448"
   538  	CurveNistP256      Curve = "P256"
   539  	CurveNistP384      Curve = "P384"
   540  	CurveNistP521      Curve = "P521"
   541  	CurveSecP256k1     Curve = "SecP256k1"
   542  	CurveBrainpoolP256 Curve = "BrainpoolP256"
   543  	CurveBrainpoolP384 Curve = "BrainpoolP384"
   544  	CurveBrainpoolP512 Curve = "BrainpoolP512"
   545  )
   546  
   547  // TrustLevel represents a trust level per RFC4880 5.2.3.13
   548  type TrustLevel uint8
   549  
   550  // TrustAmount represents a trust amount per RFC4880 5.2.3.13
   551  type TrustAmount uint8
   552  

View as plain text