Module: OpenPGP::Armor

Defined in:
lib/openpgp/armor.rb

Overview

OpenPGP ASCII Armor utilities.

See Also:

Defined Under Namespace

Modules: Markers Classes: CRCError

Class Method Summary (collapse)

Class Method Details

+ (String) decode(text, marker = nil, options = {})

Parameters:

  • (String) text
  • (String, #to_s) marker (defaults to: nil)
  • (Hash{Symbol => Object}) options (defaults to: {})

Options Hash (options):

  • (Boolean) :crc — default: false

Returns:

  • (String)

See Also:



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/openpgp/armor.rb', line 75

def self.decode(text, marker = nil, options = {})
  data, crc, state = Buffer.new, nil, :begin

  text.each_line do |line|
    line.chomp!
    case state
      when :begin
        case line
          when /^-----BEGIN PGP ([^-]+)-----$/
            state = :head if marker.nil? || marker(marker) == $1
        end
      when :head
        state = :body if line =~ /^\s*$/
      when :body
        case line
          when /^=(....)$/
            crc = ("\0" << decode64($1)).unpack('N').first
            state = :end
          when /^-----END PGP ([^-]+)-----$/
            state = :end
          else
            data << decode64(line)
        end
      when :end
        break
    end
  end

  data = data.string
  if options[:crc] && crc != (crc_data = OpenPGP.crc24(data))
    raise CRCError.new("ASCII armor says 0x#{crc.to_s(16)}, but data has 0x#{crc_data.to_s(16)}")
  end
  data
end

+ (String) decode64(input) (protected)

Returns the Base64-decoded version of input.

Parameters:

  • (String) input

Returns:

  • (String)


142
143
144
# File 'lib/openpgp/armor.rb', line 142

def self.decode64(input)
  input.unpack('m').first
end

+ (String) encode(data, marker = :message, options = {})

Parameters:

  • (String) data
  • (String, #to_s) marker (defaults to: :message)
  • (Hash{Symbol => Object}) options (defaults to: {})

Options Hash (options):

  • (String, #to_s) :version — default: nil
  • (String, #to_s) :comment — default: nil
  • (Hash) :headers — default: nil
  • (Integer) :line_length — default: nil

Returns:

  • (String)

See Also:



53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/openpgp/armor.rb', line 53

def self.encode(data, marker = :message, options = {})
  Buffer.write do |text|
    text << self.header(marker)     << "\n"
    text << "Version: #{options[:version]}\n" if options[:version]
    text << "Comment: #{options[:comment]}\n" if options[:comment]
    if options[:headers]
      options[:headers].each { |key, value| text << "#{key}: #{value}\n" }
    end
    text << "\n" << encode64(data, options[:line_length])
    text << "="  << encode64([OpenPGP.crc24(data)].pack('N')[1, 3])
    text << self.footer(marker)     << "\n"
  end
end

+ (String) encode64(input, line_length = nil) (protected)

Returns the Base64-encoded version of input, with a configurable output line length.

Parameters:

  • (String) input
  • (Integer) line_length (defaults to: nil)

Returns:

  • (String)


122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/openpgp/armor.rb', line 122

def self.encode64(input, line_length = nil)
  if line_length.nil?
    [input].pack('m')
  elsif line_length % 4 == 0
    [input].pack("m#{(line_length / 4) * 3}")
  else
    output = []
    [input].pack('m').delete("\n").scan(/.{1,#{line_length}}/) do
      output << $&
    end
    output << ''
    output.join("\n")
  end
end

Parameters:

  • (String, #to_s) marker

Returns:

  • (String)

See Also:



37
38
39
# File 'lib/openpgp/armor.rb', line 37

def self.footer(marker)
  "-----END PGP #{marker(marker)}-----"
end

+ (String) header(marker)

Parameters:

  • (String, #to_s) marker

Returns:

  • (String)

See Also:



29
30
31
# File 'lib/openpgp/armor.rb', line 29

def self.header(marker)
  "-----BEGIN PGP #{marker(marker)}-----"
end

+ (String) marker(marker)

Parameters:

  • (String, #to_s) marker

Returns:

  • (String)


20
21
22
23
# File 'lib/openpgp/armor.rb', line 20

def self.marker(marker)
  marker = Markers.const_get(marker.to_s.upcase.to_sym) if marker.is_a?(Symbol)
  marker.to_s.upcase
end