Class: Tem::SecPack
- Inherits:
-
Object
- Object
- Tem::SecPack
- Defined in:
- lib/tem/secpack.rb
Constant Summary collapse
- @@serialized_ivars =
[:body, :labels, :ep, :sp, :extra_bytes, :signed_bytes, :encrypted_bytes, :bound, :lines]
Instance Attribute Summary collapse
-
#body ⇒ Object
readonly
Returns the value of attribute body.
-
#bound ⇒ Object
readonly
Returns the value of attribute bound.
-
#lines ⇒ Object
readonly
Returns the value of attribute lines.
Class Method Summary collapse
Instance Method Summary collapse
- #bind(public_key, encrypt_from = 0, plaintext_from = 0) ⇒ Object
- #expand_extra_bytes ⇒ Object
-
#get_bytes(label, byte_count) ⇒ Object
Methods for interacting with the plaintext content of a SECpack.
- #get_value(label, abi_type) ⇒ Object
-
#initialize(args) ⇒ SecPack
constructor
A new instance of SecPack.
- #label_address(label_name) ⇒ Object
- #label_info_for_addr(addr) ⇒ Object
- #line_info_for_addr(addr) ⇒ Object
- #set_bytes(label, bytes) ⇒ Object
- #set_value(label, abi_type, value) ⇒ Object
- #tem_formatted_body ⇒ Object
- #to_array ⇒ Object
- #to_yaml_str ⇒ Object
- #trim_extra_bytes ⇒ Object
Constructor Details
#initialize(args) ⇒ SecPack
Returns a new instance of SecPack.
43 44 45 46 47 48 49 |
# File 'lib/tem/secpack.rb', line 43 def initialize(args) @@serialized_ivars.map { |m| self.instance_variable_set :"@#{m}", args[m] } @bound ||= false @extra_bytes ||= 0 # trim_extra_bytes if @extra_bytes == 0 end |
Instance Attribute Details
#body ⇒ Object (readonly)
Returns the value of attribute body.
26 27 28 |
# File 'lib/tem/secpack.rb', line 26 def body @body end |
#bound ⇒ Object (readonly)
Returns the value of attribute bound.
26 27 28 |
# File 'lib/tem/secpack.rb', line 26 def bound @bound end |
#lines ⇒ Object (readonly)
Returns the value of attribute lines.
27 28 29 |
# File 'lib/tem/secpack.rb', line 27 def lines @lines end |
Class Method Details
.new_from_array(array) ⇒ Object
7 8 9 10 11 |
# File 'lib/tem/secpack.rb', line 7 def self.new_from_array(array) arg_hash = { } @@serialized_ivars.each_with_index { |name, i| arg_hash[name] = array[i] } self.new arg_hash end |
.new_from_yaml_str(yaml_str) ⇒ Object
13 14 15 16 |
# File 'lib/tem/secpack.rb', line 13 def self.new_from_yaml_str(yaml_str) array = YAML.load yaml_str new_from_array array end |
Instance Method Details
#bind(public_key, encrypt_from = 0, plaintext_from = 0) ⇒ Object
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/tem/secpack.rb', line 55 def bind(public_key, encrypt_from = 0, plaintext_from = 0) encrypt_from = @labels[encrypt_from.to_sym] unless encrypt_from.kind_of? Numeric plaintext_from = @labels[plaintext_from.to_sym] unless plaintext_from.kind_of? Numeric @signed_bytes = encrypt_from @encrypted_bytes = plaintext_from - encrypt_from secpack_sig = Tem::Abi.tem_hash [tem_header, @body[0...plaintext_from]].flatten crypt = public_key.encrypt [@body[encrypt_from...plaintext_from], secpack_sig].flatten @body = [@body[0...encrypt_from], crypt, @body[plaintext_from..-1]].flatten label_delta = crypt.length - @encrypted_bytes @labels = Hash[*(@labels.map { |k, v| if v < encrypt_from [k, v] elsif v < plaintext_from [] else [k, v + label_delta] end }.flatten)] #trim_extra_bytes @bound = true end |
#expand_extra_bytes ⇒ Object
38 39 40 41 |
# File 'lib/tem/secpack.rb', line 38 def @body += [0] * @extra_bytes @extra_bytes = 0 end |
#get_bytes(label, byte_count) ⇒ Object
Methods for interacting with the plaintext content of a SECpack.
117 118 119 120 121 122 123 |
# File 'lib/tem/secpack.rb', line 117 def get_bytes(label, byte_count) raise "Unknown label #{label}" unless addr = @labels[label] bytes = @body[addr, byte_count] #trim_extra_bytes bytes end |
#get_value(label, abi_type) ⇒ Object
136 137 138 139 140 141 142 |
# File 'lib/tem/secpack.rb', line 136 def get_value(label, abi_type) raise "Unknown label #{label}" unless addr = @labels[label] value = Tem::Abi.send :"read_#{abi_type}", @body, addr #trim_extra_bytes value end |
#label_address(label_name) ⇒ Object
51 52 53 |
# File 'lib/tem/secpack.rb', line 51 def label_address(label_name) @labels[label_name.to_sym] end |
#label_info_for_addr(addr) ⇒ Object
108 109 110 111 112 113 |
# File 'lib/tem/secpack.rb', line 108 def label_info_for_addr(addr) @labels.to_a.reverse_each do |info| return info.reverse if addr >= info[1] end return [0, :__start] end |
#line_info_for_addr(addr) ⇒ Object
97 98 99 100 101 102 103 104 105 106 |
# File 'lib/tem/secpack.rb', line 97 def line_info_for_addr(addr) return nil unless @lines @lines.reverse_each do |info| # If something breaks, it's likely to happen after the opcode of the # offending instruction has been read, so assume offending_ip < ip. return info if addr >= info[0] end return @lines.first end |
#set_bytes(label, bytes) ⇒ Object
125 126 127 128 129 130 |
# File 'lib/tem/secpack.rb', line 125 def set_bytes(label, bytes) raise "Unknown label #{label}" unless addr = @labels[label] @body[addr, bytes.length] = bytes #trim_extra_bytes end |
#set_value(label, abi_type, value) ⇒ Object
132 133 134 |
# File 'lib/tem/secpack.rb', line 132 def set_value(label, abi_type, value) set_bytes label, Tem::Abi.send(:"to_#{abi_type}", value) end |
#tem_formatted_body ⇒ Object
91 92 93 94 95 |
# File 'lib/tem/secpack.rb', line 91 def tem_formatted_body # HACK: Ideally, we would allocate a bigger buffer, and then only fill part # of it. Realistically, we'll just send in extra_bytes 0s. [tem_header, @body, [0] * @extra_bytes].flatten end |
#to_array ⇒ Object
18 19 20 |
# File 'lib/tem/secpack.rb', line 18 def to_array @@serialized_ivars.map { |m| self.instance_variable_get :"@#{m}" } end |
#to_yaml_str ⇒ Object
22 23 24 |
# File 'lib/tem/secpack.rb', line 22 def to_yaml_str self.to_array.to_yaml.to_s end |
#trim_extra_bytes ⇒ Object
29 30 31 32 33 34 35 36 |
# File 'lib/tem/secpack.rb', line 29 def trim_extra_bytes @extra_bytes = 0 while @extra_bytes < @body.length break if @body[-@extra_bytes - 1] != 0 @extra_bytes += 1 end @body.slice! @body.length - @extra_bytes, @extra_bytes end |