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.
5 // Package packet implements parsing and serialization of OpenPGP packets, as
6 // specified in RFC 4880.
7 package packet // import "golang.org/x/crypto/openpgp/packet"
14 "golang.org/x/crypto/cast5"
15 "golang.org/x/crypto/openpgp/errors"
20 // readFull is the same as io.ReadFull except that reading zero bytes returns
21 // ErrUnexpectedEOF rather than EOF.
22 func readFull(r io.Reader, buf []byte) (n int, err error) {
23 n, err = io.ReadFull(r, buf)
25 err = io.ErrUnexpectedEOF
30 // readLength reads an OpenPGP length from r. See RFC 4880, section 4.2.2.
31 func readLength(r io.Reader) (length int64, isPartial bool, err error) {
33 _, err = readFull(r, buf[:1])
39 length = int64(buf[0])
41 length = int64(buf[0]-192) << 8
42 _, err = readFull(r, buf[0:1])
46 length += int64(buf[0]) + 192
48 length = int64(1) << (buf[0] & 0x1f)
51 _, err = readFull(r, buf[0:4])
55 length = int64(buf[0])<<24 |
63 // partialLengthReader wraps an io.Reader and handles OpenPGP partial lengths.
64 // The continuation lengths are parsed and removed from the stream and EOF is
65 // returned at the end of the packet. See RFC 4880, section 4.2.2.4.
66 type partialLengthReader struct {
72 func (r *partialLengthReader) Read(p []byte) (n int, err error) {
73 for r.remaining == 0 {
77 r.remaining, r.isPartial, err = readLength(r.r)
83 toRead := int64(len(p))
84 if toRead > r.remaining {
88 n, err = r.r.Read(p[:int(toRead)])
89 r.remaining -= int64(n)
90 if n < int(toRead) && err == io.EOF {
91 err = io.ErrUnexpectedEOF
96 // partialLengthWriter writes a stream of data using OpenPGP partial lengths.
97 // See RFC 4880, section 4.2.2.4.
98 type partialLengthWriter struct {
103 func (w *partialLengthWriter) Write(p []byte) (n int, err error) {
105 for power := uint(14); power < 32; power-- {
108 w.lengthByte[0] = 224 + uint8(power)
109 _, err = w.w.Write(w.lengthByte[:])
114 m, err = w.w.Write(p[:l])
127 func (w *partialLengthWriter) Close() error {
129 _, err := w.w.Write(w.lengthByte[:])
136 // A spanReader is an io.LimitReader, but it returns ErrUnexpectedEOF if the
137 // underlying Reader returns EOF before the limit has been reached.
138 type spanReader struct {
143 func (l *spanReader) Read(p []byte) (n int, err error) {
147 if int64(len(p)) > l.n {
152 if l.n > 0 && err == io.EOF {
153 err = io.ErrUnexpectedEOF
158 // readHeader parses a packet header and returns an io.Reader which will return
159 // the contents of the packet. See RFC 4880, section 4.2.
160 func readHeader(r io.Reader) (tag packetType, length int64, contents io.Reader, err error) {
162 _, err = io.ReadFull(r, buf[:1])
166 if buf[0]&0x80 == 0 {
167 err = errors.StructuralError("tag byte does not have MSB set")
170 if buf[0]&0x40 == 0 {
172 tag = packetType((buf[0] & 0x3f) >> 2)
173 lengthType := buf[0] & 3
179 lengthBytes := 1 << lengthType
180 _, err = readFull(r, buf[0:lengthBytes])
184 for i := 0; i < lengthBytes; i++ {
186 length |= int64(buf[i])
188 contents = &spanReader{r, length}
193 tag = packetType(buf[0] & 0x3f)
194 length, isPartial, err := readLength(r)
199 contents = &partialLengthReader{
206 contents = &spanReader{r, length}
211 // serializeHeader writes an OpenPGP packet header to w. See RFC 4880, section
213 func serializeHeader(w io.Writer, ptype packetType, length int) (err error) {
217 buf[0] = 0x80 | 0x40 | byte(ptype)
219 buf[1] = byte(length)
221 } else if length < 8384 {
223 buf[1] = 192 + byte(length>>8)
224 buf[2] = byte(length)
228 buf[2] = byte(length >> 24)
229 buf[3] = byte(length >> 16)
230 buf[4] = byte(length >> 8)
231 buf[5] = byte(length)
235 _, err = w.Write(buf[:n])
239 // serializeStreamHeader writes an OpenPGP packet header to w where the
240 // length of the packet is unknown. It returns a io.WriteCloser which can be
241 // used to write the contents of the packet. See RFC 4880, section 4.2.
242 func serializeStreamHeader(w io.WriteCloser, ptype packetType) (out io.WriteCloser, err error) {
244 buf[0] = 0x80 | 0x40 | byte(ptype)
245 _, err = w.Write(buf[:])
249 out = &partialLengthWriter{w: w}
253 // Packet represents an OpenPGP packet. Users are expected to try casting
254 // instances of this interface to specific packet types.
255 type Packet interface {
256 parse(io.Reader) error
259 // consumeAll reads from the given Reader until error, returning the number of
261 func consumeAll(r io.Reader) (n int64, err error) {
266 m, err = r.Read(buf[:])
278 // packetType represents the numeric ids of the different OpenPGP packet types. See
279 // http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-2
280 type packetType uint8
283 packetTypeEncryptedKey packetType = 1
284 packetTypeSignature packetType = 2
285 packetTypeSymmetricKeyEncrypted packetType = 3
286 packetTypeOnePassSignature packetType = 4
287 packetTypePrivateKey packetType = 5
288 packetTypePublicKey packetType = 6
289 packetTypePrivateSubkey packetType = 7
290 packetTypeCompressed packetType = 8
291 packetTypeSymmetricallyEncrypted packetType = 9
292 packetTypeLiteralData packetType = 11
293 packetTypeUserId packetType = 13
294 packetTypePublicSubkey packetType = 14
295 packetTypeUserAttribute packetType = 17
296 packetTypeSymmetricallyEncryptedMDC packetType = 18
299 // peekVersion detects the version of a public key packet about to
300 // be read. A bufio.Reader at the original position of the io.Reader
302 func peekVersion(r io.Reader) (bufr *bufio.Reader, ver byte, err error) {
303 bufr = bufio.NewReader(r)
305 if verBuf, err = bufr.Peek(1); err != nil {
312 // Read reads a single OpenPGP packet from the given io.Reader. If there is an
313 // error parsing a packet, the whole packet is consumed from the input.
314 func Read(r io.Reader) (p Packet, err error) {
315 tag, _, contents, err := readHeader(r)
321 case packetTypeEncryptedKey:
322 p = new(EncryptedKey)
323 case packetTypeSignature:
325 // Detect signature version
326 if contents, version, err = peekVersion(contents); err != nil {
334 case packetTypeSymmetricKeyEncrypted:
335 p = new(SymmetricKeyEncrypted)
336 case packetTypeOnePassSignature:
337 p = new(OnePassSignature)
338 case packetTypePrivateKey, packetTypePrivateSubkey:
339 pk := new(PrivateKey)
340 if tag == packetTypePrivateSubkey {
344 case packetTypePublicKey, packetTypePublicSubkey:
346 if contents, version, err = peekVersion(contents); err != nil {
349 isSubkey := tag == packetTypePublicSubkey
351 p = &PublicKeyV3{IsSubkey: isSubkey}
353 p = &PublicKey{IsSubkey: isSubkey}
355 case packetTypeCompressed:
357 case packetTypeSymmetricallyEncrypted:
358 p = new(SymmetricallyEncrypted)
359 case packetTypeLiteralData:
361 case packetTypeUserId:
363 case packetTypeUserAttribute:
364 p = new(UserAttribute)
365 case packetTypeSymmetricallyEncryptedMDC:
366 se := new(SymmetricallyEncrypted)
370 err = errors.UnknownPacketTypeError(tag)
373 err = p.parse(contents)
381 // SignatureType represents the different semantic meanings of an OpenPGP
382 // signature. See RFC 4880, section 5.2.1.
383 type SignatureType uint8
386 SigTypeBinary SignatureType = 0
388 SigTypeGenericCert = 0x10
389 SigTypePersonaCert = 0x11
390 SigTypeCasualCert = 0x12
391 SigTypePositiveCert = 0x13
392 SigTypeSubkeyBinding = 0x18
393 SigTypePrimaryKeyBinding = 0x19
394 SigTypeDirectSignature = 0x1F
395 SigTypeKeyRevocation = 0x20
396 SigTypeSubkeyRevocation = 0x28
399 // PublicKeyAlgorithm represents the different public key system specified for
401 // http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-12
402 type PublicKeyAlgorithm uint8
405 PubKeyAlgoRSA PublicKeyAlgorithm = 1
406 PubKeyAlgoRSAEncryptOnly PublicKeyAlgorithm = 2
407 PubKeyAlgoRSASignOnly PublicKeyAlgorithm = 3
408 PubKeyAlgoElGamal PublicKeyAlgorithm = 16
409 PubKeyAlgoDSA PublicKeyAlgorithm = 17
410 // RFC 6637, Section 5.
411 PubKeyAlgoECDH PublicKeyAlgorithm = 18
412 PubKeyAlgoECDSA PublicKeyAlgorithm = 19
415 // CanEncrypt returns true if it's possible to encrypt a message to a public
416 // key of the given type.
417 func (pka PublicKeyAlgorithm) CanEncrypt() bool {
419 case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoElGamal:
425 // CanSign returns true if it's possible for a public key of the given type to
427 func (pka PublicKeyAlgorithm) CanSign() bool {
429 case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoDSA, PubKeyAlgoECDSA:
435 // CipherFunction represents the different block ciphers specified for OpenPGP. See
436 // http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-13
437 type CipherFunction uint8
440 Cipher3DES CipherFunction = 2
441 CipherCAST5 CipherFunction = 3
442 CipherAES128 CipherFunction = 7
443 CipherAES192 CipherFunction = 8
444 CipherAES256 CipherFunction = 9
447 // KeySize returns the key size, in bytes, of cipher.
448 func (cipher CipherFunction) KeySize() int {
464 // blockSize returns the block size, in bytes, of cipher.
465 func (cipher CipherFunction) blockSize() int {
471 case CipherAES128, CipherAES192, CipherAES256:
477 // new returns a fresh instance of the given cipher.
478 func (cipher CipherFunction) new(key []byte) (block cipher.Block) {
481 block, _ = des.NewTripleDESCipher(key)
483 block, _ = cast5.NewCipher(key)
484 case CipherAES128, CipherAES192, CipherAES256:
485 block, _ = aes.NewCipher(key)
490 // readMPI reads a big integer from r. The bit length returned is the bit
491 // length that was specified in r. This is preserved so that the integer can be
492 // reserialized exactly.
493 func readMPI(r io.Reader) (mpi []byte, bitLength uint16, err error) {
495 _, err = readFull(r, buf[0:])
499 bitLength = uint16(buf[0])<<8 | uint16(buf[1])
500 numBytes := (int(bitLength) + 7) / 8
501 mpi = make([]byte, numBytes)
502 _, err = readFull(r, mpi)
506 // mpiLength returns the length of the given *big.Int when serialized as an
508 func mpiLength(n *big.Int) (mpiLengthInBytes int) {
509 mpiLengthInBytes = 2 /* MPI length */
510 mpiLengthInBytes += (n.BitLen() + 7) / 8
514 // writeMPI serializes a big integer to w.
515 func writeMPI(w io.Writer, bitLength uint16, mpiBytes []byte) (err error) {
516 _, err = w.Write([]byte{byte(bitLength >> 8), byte(bitLength)})
518 _, err = w.Write(mpiBytes)
523 // writeBig serializes a *big.Int to w.
524 func writeBig(w io.Writer, i *big.Int) error {
525 return writeMPI(w, uint16(i.BitLen()), i.Bytes())
528 // CompressionAlgo Represents the different compression algorithms
529 // supported by OpenPGP (except for BZIP2, which is not currently
530 // supported). See Section 9.3 of RFC 4880.
531 type CompressionAlgo uint8
534 CompressionNone CompressionAlgo = 0
535 CompressionZIP CompressionAlgo = 1
536 CompressionZLIB CompressionAlgo = 2