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 packetTypeLiteralData packetType = 11 315 packetTypeUserId packetType = 13 316 packetTypePublicSubkey packetType = 14 317 packetTypeUserAttribute packetType = 17 318 packetTypeSymmetricallyEncryptedMDC packetType = 18 319 packetTypeAEADEncrypted packetType = 20 320) 321 322// EncryptedDataPacket holds encrypted data. It is currently implemented by 323// SymmetricallyEncrypted and AEADEncrypted. 324type 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. 330func 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 err = errors.UnsupportedError("Symmetrically encrypted packets without MDC are not supported") 358 case packetTypeLiteralData: 359 p = new(LiteralData) 360 case packetTypeUserId: 361 p = new(UserId) 362 case packetTypeUserAttribute: 363 p = new(UserAttribute) 364 case packetTypeSymmetricallyEncryptedMDC: 365 se := new(SymmetricallyEncrypted) 366 se.MDC = 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. 384type SignatureType uint8 385 386const ( 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 404type PublicKeyAlgorithm uint8 405 406const ( 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. 423func (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. 433func (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 443type CipherFunction algorithm.CipherFunction 444 445const ( 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. 454func (cipher CipherFunction) KeySize() int { 455 return algorithm.CipherFunction(cipher).KeySize() 456} 457 458// blockSize returns the block size, in bytes, of cipher. 459func (cipher CipherFunction) blockSize() int { 460 return algorithm.CipherFunction(cipher).BlockSize() 461} 462 463// new returns a fresh instance of the given cipher. 464func (cipher CipherFunction) new(key []byte) (block cipher.Block) { 465 return algorithm.CipherFunction(cipher).New(key) 466} 467 468// padToKeySize left-pads a MPI with zeroes to match the length of the 469// specified RSA public. 470func padToKeySize(pub *rsa.PublicKey, b []byte) []byte { 471 k := (pub.N.BitLen() + 7) / 8 472 if len(b) >= k { 473 return b 474 } 475 bb := make([]byte, k) 476 copy(bb[len(bb)-len(b):], b) 477 return bb 478} 479 480// CompressionAlgo Represents the different compression algorithms 481// supported by OpenPGP (except for BZIP2, which is not currently 482// supported). See Section 9.3 of RFC 4880. 483type CompressionAlgo uint8 484 485const ( 486 CompressionNone CompressionAlgo = 0 487 CompressionZIP CompressionAlgo = 1 488 CompressionZLIB CompressionAlgo = 2 489) 490 491// AEADMode represents the different Authenticated Encryption with Associated 492// Data specified for OpenPGP. 493type AEADMode algorithm.AEADMode 494 495const ( 496 AEADModeEAX AEADMode = 1 497 AEADModeOCB AEADMode = 2 498 AEADModeExperimentalGCM AEADMode = 100 499) 500 501func (mode AEADMode) NonceLength() int { 502 return algorithm.AEADMode(mode).NonceLength() 503} 504 505func (mode AEADMode) TagLength() int { 506 return algorithm.AEADMode(mode).TagLength() 507} 508 509// new returns a fresh instance of the given mode. 510func (mode AEADMode) new(block cipher.Block) cipher.AEAD { 511 return algorithm.AEADMode(mode).New(block) 512} 513 514// ReasonForRevocation represents a revocation reason code as per RFC4880 515// section 5.2.3.23. 516type ReasonForRevocation uint8 517 518const ( 519 NoReason ReasonForRevocation = 0 520 KeySuperseded ReasonForRevocation = 1 521 KeyCompromised ReasonForRevocation = 2 522 KeyRetired ReasonForRevocation = 3 523) 524