Class: Errlog::Packager

Inherits:
Object
  • Object
show all
Defined in:
lib/errlog/packager.rb

Overview

Packager does (un)packing data to effectively and (where possible) safely transfer the report over the network. Normally you don’t use it directly.

Instance Method Summary collapse

Constructor Details

#initialize(app_id, app_key) ⇒ Packager

Returns a new instance of Packager.



15
16
17
18
# File 'lib/errlog/packager.rb', line 15

def initialize app_id, app_key
  @appid = app_id
  @key   = app_key.length == 16 ? app_key : Base64.decode64(app_key)
end

Instance Method Details

#decrypt(ciphertext) ⇒ Object

AES-128 decrypt the block



30
31
32
33
34
35
36
37
38
# File 'lib/errlog/packager.rb', line 30

def decrypt ciphertext
  cipher = OpenSSL::Cipher.new('AES-128-CBC')
  cipher.decrypt
  cipher.iv    = ciphertext[0..15]
  cipher.key   = @key
  data         = cipher.update(ciphertext[16..-1]) + cipher.final
  data, digest = data[0...-16], data[-16..-1]
  digest == Digest::MD5.digest(data) ? data : nil
end

#encrypt(data) ⇒ Object

AES-128 encrypt the block



21
22
23
24
25
26
27
# File 'lib/errlog/packager.rb', line 21

def encrypt data
  cipher = OpenSSL::Cipher.new('AES-128-CBC')
  cipher.encrypt
  iv         = cipher.random_iv
  cipher.key = @key
  iv + cipher.update(data) + cipher.update(Digest::MD5.digest(data)) + cipher.final
end

#pack(payload) ⇒ binary

Returns packed payload using the default block format.

Returns:

  • (binary)

    packed payload using the default block format



41
42
43
# File 'lib/errlog/packager.rb', line 41

def pack payload
  "\x00#{encrypt(Boss.dump @appid, payload)}"
end

#unpack(block) ⇒ Hash

Note:

packager can unpack v1 (boss, encrypted) and v2 (json, unencrypted) but it does not pack to v2 as it is no secure and limited to US export laws castrated platforms like iPhone and is not recommended to be used anywhere else.

to be broken (e.g. wrong credentials used)

Returns:

  • (Hash)

    unpacked payload or nil if block format is unknown or block seems



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/errlog/packager.rb', line 51

def unpack block
  case block[0].ord
    when 0
      id, payload = Boss.load_all(decrypt(block[1..-1]))
      id == @appid ? payload : nil
    when 1
      data = block[1...-32]
      sign = block[-32..-1]
      if sign != Digest::SHA256.digest(data + @key)
        nil
      else
        JSON.parse Zlib::GzipReader.new(StringIO.new(data)).read
      end
    else
      nil
  end
rescue
  nil
end