Copyright 2011 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
Package packet implements parsing and serialization of OpenPGP packets, as specified in RFC 4880.
package packet // import "golang.org/x/crypto/openpgp/packet"

import (
	
	
	
	
	
	
	
	

	
	
)
readFull is the same as io.ReadFull except that reading zero bytes returns ErrUnexpectedEOF rather than EOF.
func ( io.Reader,  []byte) ( int,  error) {
	,  = io.ReadFull(, )
	if  == io.EOF {
		 = io.ErrUnexpectedEOF
	}
	return
}
readLength reads an OpenPGP length from r. See RFC 4880, section 4.2.2.
func ( io.Reader) ( int64,  bool,  error) {
	var  [4]byte
	_,  = readFull(, [:1])
	if  != nil {
		return
	}
	switch {
	case [0] < 192:
		 = int64([0])
	case [0] < 224:
		 = int64([0]-192) << 8
		_,  = readFull(, [0:1])
		if  != nil {
			return
		}
		 += int64([0]) + 192
	case [0] < 255:
		 = int64(1) << ([0] & 0x1f)
		 = true
	default:
		_,  = readFull(, [0:4])
		if  != nil {
			return
		}
		 = int64([0])<<24 |
			int64([1])<<16 |
			int64([2])<<8 |
			int64([3])
	}
	return
}
partialLengthReader wraps an io.Reader and handles OpenPGP partial lengths. The continuation lengths are parsed and removed from the stream and EOF is returned at the end of the packet. See RFC 4880, section 4.2.2.4.
type partialLengthReader struct {
	r         io.Reader
	remaining int64
	isPartial bool
}

func ( *partialLengthReader) ( []byte) ( int,  error) {
	for .remaining == 0 {
		if !.isPartial {
			return 0, io.EOF
		}
		.remaining, .isPartial,  = readLength(.r)
		if  != nil {
			return 0, 
		}
	}

	 := int64(len())
	if  > .remaining {
		 = .remaining
	}

	,  = .r.Read([:int()])
	.remaining -= int64()
	if  < int() &&  == io.EOF {
		 = io.ErrUnexpectedEOF
	}
	return
}
partialLengthWriter writes a stream of data using OpenPGP partial lengths. See RFC 4880, section 4.2.2.4.
RFC 4880 4.2.2.4: the first partial length MUST be at least 512 octets long.
const minFirstPartialWrite = 512

func ( *partialLengthWriter) ( []byte) ( int,  error) {
	 := 0
	if !.sentFirst {
		if len(.buf) > 0 || len() < minFirstPartialWrite {
			 = len(.buf)
			.buf = append(.buf, ...)
			if len(.buf) < minFirstPartialWrite {
				return len(), nil
			}
			 = .buf
			.buf = nil
		}
		.sentFirst = true
	}

	 := uint8(30)
	for len() > 0 {
		 := 1 << 
		if len() <  {
			 = uint8(bits.Len32(uint32(len()))) - 1
			 = 1 << 
		}
		.lengthByte[0] = 224 + 
		_,  = .w.Write(.lengthByte[:])
		if  == nil {
			var  int
			,  = .w.Write([:])
			 += 
		}
		if  != nil {
			if  <  {
				return 0, 
			}
			return  - , 
		}
		 = [:]
	}
	return  - , nil
}

func ( *partialLengthWriter) () error {
In this case we can't send a 512 byte packet. Just send what we have.
		 := .buf
		.sentFirst = true
		.buf = nil
		if ,  := .Write();  != nil {
			return 
		}
	}

	.lengthByte[0] = 0
	,  := .w.Write(.lengthByte[:])
	if  != nil {
		return 
	}
	return .w.Close()
}
A spanReader is an io.LimitReader, but it returns ErrUnexpectedEOF if the underlying Reader returns EOF before the limit has been reached.
type spanReader struct {
	r io.Reader
	n int64
}

func ( *spanReader) ( []byte) ( int,  error) {
	if .n <= 0 {
		return 0, io.EOF
	}
	if int64(len()) > .n {
		 = [0:.n]
	}
	,  = .r.Read()
	.n -= int64()
	if .n > 0 &&  == io.EOF {
		 = io.ErrUnexpectedEOF
	}
	return
}
readHeader parses a packet header and returns an io.Reader which will return the contents of the packet. See RFC 4880, section 4.2.
func ( io.Reader) ( packetType,  int64,  io.Reader,  error) {
	var  [4]byte
	_,  = io.ReadFull(, [:1])
	if  != nil {
		return
	}
	if [0]&0x80 == 0 {
		 = errors.StructuralError("tag byte does not have MSB set")
		return
	}
Old format packet
		 = packetType(([0] & 0x3f) >> 2)
		 := [0] & 3
		if  == 3 {
			 = -1
			 = 
			return
		}
		 := 1 << 
		_,  = readFull(, [0:])
		if  != nil {
			return
		}
		for  := 0;  < ; ++ {
			 <<= 8
			 |= int64([])
		}
		 = &spanReader{, }
		return
	}
New format packet
	 = packetType([0] & 0x3f)
	, ,  := readLength()
	if  != nil {
		return
	}
	if  {
		 = &partialLengthReader{
			remaining: ,
			isPartial: true,
			r:         ,
		}
		 = -1
	} else {
		 = &spanReader{, }
	}
	return
}
serializeHeader writes an OpenPGP packet header to w. See RFC 4880, section 4.2.
func ( io.Writer,  packetType,  int) ( error) {
	var  [6]byte
	var  int

	[0] = 0x80 | 0x40 | byte()
	if  < 192 {
		[1] = byte()
		 = 2
	} else if  < 8384 {
		 -= 192
		[1] = 192 + byte(>>8)
		[2] = byte()
		 = 3
	} else {
		[1] = 255
		[2] = byte( >> 24)
		[3] = byte( >> 16)
		[4] = byte( >> 8)
		[5] = byte()
		 = 6
	}

	_,  = .Write([:])
	return
}
serializeStreamHeader writes an OpenPGP packet header to w where the length of the packet is unknown. It returns a io.WriteCloser which can be used to write the contents of the packet. See RFC 4880, section 4.2.
func ( io.WriteCloser,  packetType) ( io.WriteCloser,  error) {
	var  [1]byte
	[0] = 0x80 | 0x40 | byte()
	_,  = .Write([:])
	if  != nil {
		return
	}
	 = &partialLengthWriter{w: }
	return
}
Packet represents an OpenPGP packet. Users are expected to try casting instances of this interface to specific packet types.
type Packet interface {
	parse(io.Reader) error
}
consumeAll reads from the given Reader until error, returning the number of bytes read.
func ( io.Reader) ( int64,  error) {
	var  int
	var  [1024]byte

	for {
		,  = .Read([:])
		 += int64()
		if  == io.EOF {
			 = nil
			return
		}
		if  != nil {
			return
		}
	}
}
peekVersion detects the version of a public key packet about to be read. A bufio.Reader at the original position of the io.Reader is returned.
func ( io.Reader) ( *bufio.Reader,  byte,  error) {
	 = bufio.NewReader()
	var  []byte
	if ,  = .Peek(1);  != nil {
		return
	}
	 = [0]
	return
}
Read reads a single OpenPGP packet from the given io.Reader. If there is an error parsing a packet, the whole packet is consumed from the input.
func ( io.Reader) ( Packet,  error) {
	, , ,  := readHeader()
	if  != nil {
		return
	}

	switch  {
	case packetTypeEncryptedKey:
		 = new(EncryptedKey)
	case packetTypeSignature:
Detect signature version
		if , ,  = peekVersion();  != nil {
			return
		}
		if  < 4 {
			 = new(SignatureV3)
		} else {
			 = new(Signature)
		}
	case packetTypeSymmetricKeyEncrypted:
		 = new(SymmetricKeyEncrypted)
	case packetTypeOnePassSignature:
		 = new(OnePassSignature)
	case packetTypePrivateKey, packetTypePrivateSubkey:
		 := new(PrivateKey)
		if  == packetTypePrivateSubkey {
			.IsSubkey = true
		}
		 = 
	case packetTypePublicKey, packetTypePublicSubkey:
		var  byte
		if , ,  = peekVersion();  != nil {
			return
		}
		 :=  == packetTypePublicSubkey
		if  < 4 {
			 = &PublicKeyV3{IsSubkey: }
		} else {
			 = &PublicKey{IsSubkey: }
		}
	case packetTypeCompressed:
		 = new(Compressed)
	case packetTypeSymmetricallyEncrypted:
		 = new(SymmetricallyEncrypted)
	case packetTypeLiteralData:
		 = new(LiteralData)
	case packetTypeUserId:
		 = new(UserId)
	case packetTypeUserAttribute:
		 = new(UserAttribute)
	case packetTypeSymmetricallyEncryptedMDC:
		 := new(SymmetricallyEncrypted)
		.MDC = true
		 = 
	default:
		 = errors.UnknownPacketTypeError()
	}
	if  != nil {
		 = .parse()
	}
	if  != nil {
		consumeAll()
	}
	return
}
SignatureType represents the different semantic meanings of an OpenPGP signature. See RFC 4880, section 5.2.1.
PublicKeyAlgorithm represents the different public key system specified for OpenPGP. See http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-12
Deprecated in RFC 4880, Section 13.5. Use key flags instead.
CanEncrypt returns true if it's possible to encrypt a message to a public key of the given type.
CanSign returns true if it's possible for a public key of the given type to sign a message.
CipherFunction represents the different block ciphers specified for OpenPGP. See http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-13
KeySize returns the key size, in bytes, of cipher.
func ( CipherFunction) () int {
	switch  {
	case Cipher3DES:
		return 24
	case CipherCAST5:
		return cast5.KeySize
	case CipherAES128:
		return 16
	case CipherAES192:
		return 24
	case CipherAES256:
		return 32
	}
	return 0
}
blockSize returns the block size, in bytes, of cipher.
func ( CipherFunction) () int {
	switch  {
	case Cipher3DES:
		return des.BlockSize
	case CipherCAST5:
		return 8
	case CipherAES128, CipherAES192, CipherAES256:
		return 16
	}
	return 0
}
new returns a fresh instance of the given cipher.
func ( CipherFunction) ( []byte) ( cipher.Block) {
	switch  {
	case Cipher3DES:
		, _ = des.NewTripleDESCipher()
	case CipherCAST5:
		, _ = cast5.NewCipher()
	case CipherAES128, CipherAES192, CipherAES256:
		, _ = aes.NewCipher()
	}
	return
}
readMPI reads a big integer from r. The bit length returned is the bit length that was specified in r. This is preserved so that the integer can be reserialized exactly.
func ( io.Reader) ( []byte,  uint16,  error) {
	var  [2]byte
	_,  = readFull(, [0:])
	if  != nil {
		return
	}
	 = uint16([0])<<8 | uint16([1])
	 := (int() + 7) / 8
	 = make([]byte, )
According to RFC 4880 3.2. we should check that the MPI has no leading zeroes (at least when not an encrypted MPI?), but this implementation does generate leading zeroes, so we keep accepting them.
	return
}
writeMPI serializes a big integer to w.
Note that we can produce leading zeroes, in violation of RFC 4880 3.2. Implementations seem to be tolerant of them, and stripping them would make it complex to guarantee matching re-serialization.
	_,  = .Write([]byte{byte( >> 8), byte()})
	if  == nil {
		_,  = .Write()
	}
	return
}
writeBig serializes a *big.Int to w.
func ( io.Writer,  *big.Int) error {
	return writeMPI(, uint16(.BitLen()), .Bytes())
}
padToKeySize left-pads a MPI with zeroes to match the length of the specified RSA public.
func ( *rsa.PublicKey,  []byte) []byte {
	 := (.N.BitLen() + 7) / 8
	if len() >=  {
		return 
	}
	 := make([]byte, )
	copy([len()-len():], )
	return 
}
CompressionAlgo Represents the different compression algorithms supported by OpenPGP (except for BZIP2, which is not currently supported). See Section 9.3 of RFC 4880.