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"
18 "golang.org/x/crypto/cast5"
19 "golang.org/x/crypto/openpgp/errors"
22 // readFull is the same as io.ReadFull except that reading zero bytes returns
23 // ErrUnexpectedEOF rather than EOF.
24 func readFull(r io.Reader, buf []byte) (n int, err error) {
25 n, err = io.ReadFull(r, buf)
27 err = io.ErrUnexpectedEOF
32 // readLength reads an OpenPGP length from r. See RFC 4880, section 4.2.2.
33 func readLength(r io.Reader) (length int64, isPartial bool, err error) {
35 _, err = readFull(r, buf[:1])
41 length = int64(buf[0])
43 length = int64(buf[0]-192) << 8
44 _, err = readFull(r, buf[0:1])
48 length += int64(buf[0]) + 192
50 length = int64(1) << (buf[0] & 0x1f)
53 _, err = readFull(r, buf[0:4])
57 length = int64(buf[0])<<24 |
65 // partialLengthReader wraps an io.Reader and handles OpenPGP partial lengths.
66 // The continuation lengths are parsed and removed from the stream and EOF is
67 // returned at the end of the packet. See RFC 4880, section 4.2.2.4.
68 type partialLengthReader struct {
74 func (r *partialLengthReader) Read(p []byte) (n int, err error) {
75 for r.remaining == 0 {
79 r.remaining, r.isPartial, err = readLength(r.r)
85 toRead := int64(len(p))
86 if toRead > r.remaining {
90 n, err = r.r.Read(p[:int(toRead)])
91 r.remaining -= int64(n)
92 if n < int(toRead) && err == io.EOF {
93 err = io.ErrUnexpectedEOF
98 // partialLengthWriter writes a stream of data using OpenPGP partial lengths.
99 // See RFC 4880, section 4.2.2.4.
100 type partialLengthWriter struct {
105 func (w *partialLengthWriter) Write(p []byte) (n int, err error) {
107 for power := uint(14); power < 32; power-- {
110 w.lengthByte[0] = 224 + uint8(power)
111 _, err = w.w.Write(w.lengthByte[:])
116 m, err = w.w.Write(p[:l])
129 func (w *partialLengthWriter) Close() error {
131 _, err := w.w.Write(w.lengthByte[:])
138 // A spanReader is an io.LimitReader, but it returns ErrUnexpectedEOF if the
139 // underlying Reader returns EOF before the limit has been reached.
140 type spanReader struct {
145 func (l *spanReader) Read(p []byte) (n int, err error) {
149 if int64(len(p)) > l.n {
154 if l.n > 0 && err == io.EOF {
155 err = io.ErrUnexpectedEOF
160 // readHeader parses a packet header and returns an io.Reader which will return
161 // the contents of the packet. See RFC 4880, section 4.2.
162 func readHeader(r io.Reader) (tag packetType, length int64, contents io.Reader, err error) {
164 _, err = io.ReadFull(r, buf[:1])
168 if buf[0]&0x80 == 0 {
169 err = errors.StructuralError("tag byte does not have MSB set")
172 if buf[0]&0x40 == 0 {
174 tag = packetType((buf[0] & 0x3f) >> 2)
175 lengthType := buf[0] & 3
181 lengthBytes := 1 << lengthType
182 _, err = readFull(r, buf[0:lengthBytes])
186 for i := 0; i < lengthBytes; i++ {
188 length |= int64(buf[i])
190 contents = &spanReader{r, length}
195 tag = packetType(buf[0] & 0x3f)
196 length, isPartial, err := readLength(r)
201 contents = &partialLengthReader{
208 contents = &spanReader{r, length}
213 // serializeHeader writes an OpenPGP packet header to w. See RFC 4880, section
215 func serializeHeader(w io.Writer, ptype packetType, length int) (err error) {
219 buf[0] = 0x80 | 0x40 | byte(ptype)
221 buf[1] = byte(length)
223 } else if length < 8384 {
225 buf[1] = 192 + byte(length>>8)
226 buf[2] = byte(length)
230 buf[2] = byte(length >> 24)
231 buf[3] = byte(length >> 16)
232 buf[4] = byte(length >> 8)
233 buf[5] = byte(length)
237 _, err = w.Write(buf[:n])
241 // serializeStreamHeader writes an OpenPGP packet header to w where the
242 // length of the packet is unknown. It returns a io.WriteCloser which can be
243 // used to write the contents of the packet. See RFC 4880, section 4.2.
244 func serializeStreamHeader(w io.WriteCloser, ptype packetType) (out io.WriteCloser, err error) {
246 buf[0] = 0x80 | 0x40 | byte(ptype)
247 _, err = w.Write(buf[:])
251 out = &partialLengthWriter{w: w}
255 // Packet represents an OpenPGP packet. Users are expected to try casting
256 // instances of this interface to specific packet types.
257 type Packet interface {
258 parse(io.Reader) error
261 // consumeAll reads from the given Reader until error, returning the number of
263 func consumeAll(r io.Reader) (n int64, err error) {
268 m, err = r.Read(buf[:])
280 // packetType represents the numeric ids of the different OpenPGP packet types. See
281 // http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-2
282 type packetType uint8
285 packetTypeEncryptedKey packetType = 1
286 packetTypeSignature packetType = 2
287 packetTypeSymmetricKeyEncrypted packetType = 3
288 packetTypeOnePassSignature packetType = 4
289 packetTypePrivateKey packetType = 5
290 packetTypePublicKey packetType = 6
291 packetTypePrivateSubkey packetType = 7
292 packetTypeCompressed packetType = 8
293 packetTypeSymmetricallyEncrypted packetType = 9
294 packetTypeLiteralData packetType = 11
295 packetTypeUserId packetType = 13
296 packetTypePublicSubkey packetType = 14
297 packetTypeUserAttribute packetType = 17
298 packetTypeSymmetricallyEncryptedMDC packetType = 18
301 // peekVersion detects the version of a public key packet about to
302 // be read. A bufio.Reader at the original position of the io.Reader
304 func peekVersion(r io.Reader) (bufr *bufio.Reader, ver byte, err error) {
305 bufr = bufio.NewReader(r)
307 if verBuf, err = bufr.Peek(1); err != nil {
314 // Read reads a single OpenPGP packet from the given io.Reader. If there is an
315 // error parsing a packet, the whole packet is consumed from the input.
316 func Read(r io.Reader) (p Packet, err error) {
317 tag, _, contents, err := readHeader(r)
323 case packetTypeEncryptedKey:
324 p = new(EncryptedKey)
325 case packetTypeSignature:
327 // Detect signature version
328 if contents, version, err = peekVersion(contents); err != nil {
336 case packetTypeSymmetricKeyEncrypted:
337 p = new(SymmetricKeyEncrypted)
338 case packetTypeOnePassSignature:
339 p = new(OnePassSignature)
340 case packetTypePrivateKey, packetTypePrivateSubkey:
341 pk := new(PrivateKey)
342 if tag == packetTypePrivateSubkey {
346 case packetTypePublicKey, packetTypePublicSubkey:
348 if contents, version, err = peekVersion(contents); err != nil {
351 isSubkey := tag == packetTypePublicSubkey
353 p = &PublicKeyV3{IsSubkey: isSubkey}
355 p = &PublicKey{IsSubkey: isSubkey}
357 case packetTypeCompressed:
359 case packetTypeSymmetricallyEncrypted:
360 p = new(SymmetricallyEncrypted)
361 case packetTypeLiteralData:
363 case packetTypeUserId:
365 case packetTypeUserAttribute:
366 p = new(UserAttribute)
367 case packetTypeSymmetricallyEncryptedMDC:
368 se := new(SymmetricallyEncrypted)
372 err = errors.UnknownPacketTypeError(tag)
375 err = p.parse(contents)
383 // SignatureType represents the different semantic meanings of an OpenPGP
384 // signature. See RFC 4880, section 5.2.1.
385 type SignatureType uint8
388 SigTypeBinary SignatureType = 0
390 SigTypeGenericCert = 0x10
391 SigTypePersonaCert = 0x11
392 SigTypeCasualCert = 0x12
393 SigTypePositiveCert = 0x13
394 SigTypeSubkeyBinding = 0x18
395 SigTypePrimaryKeyBinding = 0x19
396 SigTypeDirectSignature = 0x1F
397 SigTypeKeyRevocation = 0x20
398 SigTypeSubkeyRevocation = 0x28
401 // PublicKeyAlgorithm represents the different public key system specified for
403 // http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-12
404 type PublicKeyAlgorithm uint8
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
414 // Deprecated in RFC 4880, Section 13.5. Use key flags instead.
415 PubKeyAlgoRSAEncryptOnly PublicKeyAlgorithm = 2
416 PubKeyAlgoRSASignOnly PublicKeyAlgorithm = 3
419 // CanEncrypt returns true if it's possible to encrypt a message to a public
420 // key of the given type.
421 func (pka PublicKeyAlgorithm) CanEncrypt() bool {
423 case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoElGamal:
429 // CanSign returns true if it's possible for a public key of the given type to
431 func (pka PublicKeyAlgorithm) CanSign() bool {
433 case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoDSA, PubKeyAlgoECDSA:
439 // CipherFunction represents the different block ciphers specified for OpenPGP. See
440 // http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-13
441 type CipherFunction uint8
444 Cipher3DES CipherFunction = 2
445 CipherCAST5 CipherFunction = 3
446 CipherAES128 CipherFunction = 7
447 CipherAES192 CipherFunction = 8
448 CipherAES256 CipherFunction = 9
451 // KeySize returns the key size, in bytes, of cipher.
452 func (cipher CipherFunction) KeySize() int {
468 // blockSize returns the block size, in bytes, of cipher.
469 func (cipher CipherFunction) blockSize() int {
475 case CipherAES128, CipherAES192, CipherAES256:
481 // new returns a fresh instance of the given cipher.
482 func (cipher CipherFunction) new(key []byte) (block cipher.Block) {
485 block, _ = des.NewTripleDESCipher(key)
487 block, _ = cast5.NewCipher(key)
488 case CipherAES128, CipherAES192, CipherAES256:
489 block, _ = aes.NewCipher(key)
494 // readMPI reads a big integer from r. The bit length returned is the bit
495 // length that was specified in r. This is preserved so that the integer can be
496 // reserialized exactly.
497 func readMPI(r io.Reader) (mpi []byte, bitLength uint16, err error) {
499 _, err = readFull(r, buf[0:])
503 bitLength = uint16(buf[0])<<8 | uint16(buf[1])
504 numBytes := (int(bitLength) + 7) / 8
505 mpi = make([]byte, numBytes)
506 _, err = readFull(r, mpi)
507 // According to RFC 4880 3.2. we should check that the MPI has no leading
508 // zeroes (at least when not an encrypted MPI?), but this implementation
509 // does generate leading zeroes, so we keep accepting them.
513 // writeMPI serializes a big integer to w.
514 func writeMPI(w io.Writer, bitLength uint16, mpiBytes []byte) (err error) {
515 // Note that we can produce leading zeroes, in violation of RFC 4880 3.2.
516 // Implementations seem to be tolerant of them, and stripping them would
517 // make it complex to guarantee matching re-serialization.
518 _, err = w.Write([]byte{byte(bitLength >> 8), byte(bitLength)})
520 _, err = w.Write(mpiBytes)
525 // writeBig serializes a *big.Int to w.
526 func writeBig(w io.Writer, i *big.Int) error {
527 return writeMPI(w, uint16(i.BitLen()), i.Bytes())
530 // padToKeySize left-pads a MPI with zeroes to match the length of the
531 // specified RSA public.
532 func padToKeySize(pub *rsa.PublicKey, b []byte) []byte {
533 k := (pub.N.BitLen() + 7) / 8
537 bb := make([]byte, k)
538 copy(bb[len(bb)-len(b):], b)
542 // CompressionAlgo Represents the different compression algorithms
543 // supported by OpenPGP (except for BZIP2, which is not currently
544 // supported). See Section 9.3 of RFC 4880.
545 type CompressionAlgo uint8
548 CompressionNone CompressionAlgo = 0
549 CompressionZIP CompressionAlgo = 1
550 CompressionZLIB CompressionAlgo = 2