class OpenPGP::Packet

OpenPGP packet.

@see tools.ietf.org/html/rfc4880#section-4.1 @see tools.ietf.org/html/rfc4880#section-4.3

Attributes

data[RW]
size[RW]
tag[RW]

Public Class Methods

for(tag) click to toggle source

Returns the implementation class for a packet tag.

@param [Integer, to_i] tag @return [Class]

# File lib/openpgp/packet.rb, line 15
def self.for(tag)
  @@tags[tag.to_i] || self
end
new(options = {}, &block) click to toggle source

@param [Hash{Symbol => Object}] options

# File lib/openpgp/packet.rb, line 103
def initialize(options = {}, &block)
  options.each { |k, v| send("#{k}=", v) }
  block.call(self) if block_given?
end
parse(data) click to toggle source

Parses an OpenPGP packet.

@param [Buffer, to_str] data @return [Packet] @see tools.ietf.org/html/rfc4880#section-4.2

# File lib/openpgp/packet.rb, line 33
def self.parse(data)
  data = Buffer.new(data.to_str) if data.respond_to?(:to_str)

  unless data.eof?
    new = ((tag = data.getbyte) & 64).nonzero? # bit 6 indicates new packet format if set
    data.ungetbyte(tag) rescue data.ungetc(tag.ord) # FIXME in backports/1.8.7
    send(new ? :parse_new_format : :parse_old_format, data)
  end
end
parse_body(body, options = {}) click to toggle source

@param [Buffer] body @param [Hash{Symbol => Object}] options @return [Packet]

# File lib/openpgp/packet.rb, line 97
def self.parse_body(body, options = {})
  self.new(options)
end
parse_new_format(data) click to toggle source

Parses a new-format (RFC 4880) OpenPGP packet.

@param [Buffer, to_str] data @return [Packet] @see tools.ietf.org/html/rfc4880#section-4.2.2

# File lib/openpgp/packet.rb, line 49
def self.parse_new_format(data)
  tag = data.getbyte & 63
  len = data.getbyte

  case len
    when 0..191   # 4.2.2.1. One-Octet Lengths
      data_length = len
    when 192..223 # 4.2.2.2. Two-Octet Lengths
      data_length = ((len - 192) << 8) + data.getbyte + 192
    when 224..254 # 4.2.2.4. Partial Body Lengths
      data_length = 1 << (len & 0x1f)
    when 255      # 4.2.2.3. Five-Octet Lengths
      data_length = (data.getbyte << 24) | (data.getbyte << 16) | (data.getbyte << 8) | data.getbyte
  end

  Packet.for(tag).parse_body(Buffer.new(data.read(data_length)), :tag => tag)
end
parse_old_format(data) click to toggle source

Parses an old-format (PGP 2.6.x) OpenPGP packet.

@param [Buffer, to_str] data @return [Packet] @see tools.ietf.org/html/rfc4880#section-4.2.1

# File lib/openpgp/packet.rb, line 73
def self.parse_old_format(data)
  len = (tag = data.getbyte) & 3
  tag = (tag >> 2) & 15

  case len
    when 0 # The packet has a one-octet length. The header is 2 octets long.
      data_length = data.getbyte
    when 1 # The packet has a two-octet length. The header is 3 octets long.
      data_length = data.read(2).unpack('n').first
    when 2 # The packet has a four-octet length. The header is 5 octets long.
      data_length = data.read(4).unpack('N').first
    when 3 # The packet is of indeterminate length. The header is 1 octet long.
      data_length = false # read to EOF
    else
      raise "Invalid OpenPGP packet length-type: expected 0..3 but got #{len}"
  end

  Packet.for(tag).parse_body(Buffer.new(data_length ? data.read(data_length) : data.read), :tag => tag)
end
tag() click to toggle source

Returns the packet tag for this class.

@return [Integer]

# File lib/openpgp/packet.rb, line 23
def self.tag
  @@tags.index(self)
end

Public Instance Methods

body() click to toggle source

@return [String]

# File lib/openpgp/packet.rb, line 116
def body
  respond_to?(:write_body) ? Buffer.write { |buffer| write_body(buffer) } : ""
end