rasn1 0.16.2 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/rasn1/tracer.rb CHANGED
@@ -14,40 +14,48 @@ module RASN1
14
14
  # @return [Integer]
15
15
  attr_accessor :tracing_level
16
16
 
17
+ # @private
18
+ # Classes to trace
17
19
  TRACED_CLASSES = [Types::Any, Types::Choice, Types::Sequence, Types::SequenceOf, Types::Base].freeze
18
20
 
19
- # @param [IO] io
21
+ # @param io [IO] io to use to put traces
20
22
  def initialize(io)
21
23
  @io = io
22
24
  @tracing_level = 0
23
25
  end
24
26
 
25
27
  # Puts +msg+ onto {#io}.
26
- # @param [String] msg
28
+ # @param msg [String]
27
29
  # @return [void]
28
30
  def trace(msg)
29
31
  @io.puts(indent << msg)
30
32
  end
31
33
 
32
34
  # Return identation for given +level+. If +nil+, use {#tracing_level}.
33
- # @param [Integer,nil] level
35
+ # @param level [Integer,nil]
34
36
  # @return [String]
35
37
  def indent(level=nil)
36
38
  level ||= @tracing_level
37
39
  ' ' * level
38
40
  end
41
+
42
+ def higher_tracing_level
43
+ self.tracing_level += 1
44
+ yield
45
+ self.tracing_level -= 1
46
+ end
39
47
  end
40
48
 
41
49
  # Trace RASN1 parsing to +io+.
42
50
  # All parsing methods called in block are traced to +io+. Each ASN.1 element is
43
51
  # traced in a line showing element's id, its length and its data.
44
- # @param [IO] io
52
+ # @param io [IO]
53
+ # @return [void]
45
54
  # @example
46
55
  # RASN1.trace do
47
56
  # RASN1.parse("\x02\x01\x01") # puts "INTEGER id: 2 (0x02), len: 1 (0x01), data: 0x01"
48
57
  # end
49
58
  # RASN1.parse("\x01\x01\xff") # puts nothing onto STDOUT
50
- # @return [void]
51
59
  def self.trace(io=$stdout)
52
60
  @tracer = Tracer.new(io)
53
61
  Tracer::TRACED_CLASSES.each(&:start_tracing)
@@ -62,6 +70,7 @@ module RASN1
62
70
  end
63
71
 
64
72
  # @private
73
+ # @return [Tracer]
65
74
  def self.tracer
66
75
  @tracer
67
76
  end
@@ -71,6 +80,7 @@ module RASN1
71
80
  class << self
72
81
  # @private
73
82
  # Patch {#do_parse} to add tracing ability
83
+ # @return [void]
74
84
  def start_tracing
75
85
  alias_method :do_parse_without_tracing, :do_parse
76
86
  alias_method :do_parse, :do_parse_with_tracing
@@ -80,6 +90,7 @@ module RASN1
80
90
 
81
91
  # @private
82
92
  # Unpatch {#do_parse} to remove tracing ability
93
+ # @return [void]
83
94
  def stop_tracing
84
95
  alias_method :do_parse, :do_parse_without_tracing
85
96
  alias_method :do_parse_explicit, :do_parse_explicit_without_tracing
@@ -88,6 +99,7 @@ module RASN1
88
99
 
89
100
  # @private
90
101
  # Parse +der+ with tracing abillity
102
+ # @!macro do_parse
91
103
  # @see #parse!
92
104
  def do_parse_with_tracing(der, ber:)
93
105
  ret = do_parse_without_tracing(der, ber: ber)
@@ -95,10 +107,13 @@ module RASN1
95
107
  ret
96
108
  end
97
109
 
110
+ # @private
111
+ # Delegate with tracing to explicit type to generate sub-value
112
+ # @param data [String]
113
+ # @return [void]
114
+ # @see #parse!
98
115
  def do_parse_explicit_with_tracing(data)
99
- RASN1.tracer.tracing_level += 1
100
- do_parse_explicit_without_tracing(data)
101
- RASN1.tracer.tracing_level -= 1
116
+ RASN1.tracer.higher_tracing_level { do_parse_explicit_without_tracing(data) }
102
117
  end
103
118
  end
104
119
 
@@ -106,6 +121,7 @@ module RASN1
106
121
  class << self
107
122
  # @private
108
123
  # Patch {#parse!} to add tracing ability
124
+ # @return [void]
109
125
  def start_tracing
110
126
  alias_method :parse_without_tracing, :parse!
111
127
  alias_method :parse!, :parse_with_tracing
@@ -113,6 +129,7 @@ module RASN1
113
129
 
114
130
  # @private
115
131
  # Unpatch {#parse!} to remove tracing ability
132
+ # @return [void]
116
133
  def stop_tracing
117
134
  alias_method :parse!, :parse_without_tracing
118
135
  end
@@ -120,6 +137,7 @@ module RASN1
120
137
 
121
138
  # @private
122
139
  # Parse +der+ with tracing abillity
140
+ # @!macro do_parse
123
141
  # @see #parse!
124
142
  def parse_with_tracing(der, ber: false)
125
143
  RASN1.tracer.trace(self.trace)
@@ -131,6 +149,7 @@ module RASN1
131
149
  class << self
132
150
  # @private
133
151
  # Patch {#der_to_value} to add tracing ability
152
+ # @return [void]
134
153
  def start_tracing
135
154
  alias_method :der_to_value_without_tracing, :der_to_value
136
155
  alias_method :der_to_value, :der_to_value_with_tracing
@@ -138,6 +157,7 @@ module RASN1
138
157
 
139
158
  # @private
140
159
  # Unpatch {#der_to_value} to remove tracing ability
160
+ # @return [void]
141
161
  def stop_tracing
142
162
  alias_method :der_to_value, :der_to_value_without_tracing
143
163
  end
@@ -145,10 +165,9 @@ module RASN1
145
165
 
146
166
  # @private
147
167
  # der_to_value +der+ with tracing abillity
168
+ # @!macro do_parse
148
169
  def der_to_value_with_tracing(der, ber: false)
149
- RASN1.tracer.tracing_level += 1
150
- der_to_value_without_tracing(der, ber: ber)
151
- RASN1.tracer.tracing_level -= 1
170
+ RASN1.tracer.higher_tracing_level { der_to_value_without_tracing(der, ber: ber) }
152
171
  end
153
172
  end
154
173
 
@@ -156,6 +175,7 @@ module RASN1
156
175
  class << self
157
176
  # @private
158
177
  # Patch {#der_to_value} to add tracing ability
178
+ # @return [void]
159
179
  def start_tracing
160
180
  alias_method :der_to_value_without_tracing, :der_to_value
161
181
  alias_method :der_to_value, :der_to_value_with_tracing
@@ -163,6 +183,7 @@ module RASN1
163
183
 
164
184
  # @private
165
185
  # Unpatch {#der_to_value} to remove tracing ability
186
+ # @return [void]
166
187
  def stop_tracing
167
188
  alias_method :der_to_value, :der_to_value_without_tracing
168
189
  end
@@ -170,10 +191,9 @@ module RASN1
170
191
 
171
192
  # @private
172
193
  # der_to_value +der+ with tracing abillity
194
+ # @!macro do_parse
173
195
  def der_to_value_with_tracing(der, ber: false)
174
- RASN1.tracer.tracing_level += 1
175
- der_to_value_without_tracing(der, ber: ber)
176
- RASN1.tracer.tracing_level -= 1
196
+ RASN1.tracer.higher_tracing_level { der_to_value_without_tracing(der, ber: ber) }
177
197
  end
178
198
  end
179
199
  end
@@ -10,7 +10,24 @@ module RASN1
10
10
  module Types
11
11
  # ASN.1 ANY: accepts any types
12
12
  #
13
+ # ANY is often used with an {ObjectId} to detect real type.
14
+ #
15
+ # On encoding, ANY is replaced by its values (which must be an RASN1 type).
13
16
  # If `any#value` is `nil` and Any object is not {#optional?}, `any` will be encoded as a {Null} object.
17
+ #
18
+ # @example Parsing with any model
19
+ # class AnyModel < RASN1::Model
20
+ # sequence :seq,
21
+ # content: [objectid(:id), any(:data)]
22
+ # end
23
+ # model = AnyModel.new
24
+ # model.parse!("\x30\x09\x06\x03\x2a\x03\x04\x02\x02\x01\xff")
25
+ # model[:id].value #=> "1.2.3.4"
26
+ # model[:data].value #=> "\x02\x02\x01\xff"
27
+ # # As we knwon object with id 1.2.3.4 is an integer, with then parse data as such
28
+ # data = RASN1::Types::Integer.new
29
+ # data.parse!(model[:data].value)
30
+ # data.value #=> 511
14
31
  # @author Sylvain Daubert
15
32
  class Any < Base
16
33
  # @return [String] DER-formated string
@@ -27,21 +44,22 @@ module RASN1
27
44
  end
28
45
  end
29
46
 
47
+ # @return [Boolean]
30
48
  def can_build?
31
49
  value? || !optional?
32
50
  end
33
51
 
34
52
  # Parse a DER string. This method updates object: {#value} will be a DER
35
53
  # string.
36
- # @param [String] der DER string
37
- # @param [Boolean] ber if +true+, accept BER encoding
54
+ # @param der [String] DER string
55
+ # @param ber [Boolean] if +true+, accept BER encoding
38
56
  # @return [Integer] total number of parsed bytes
39
57
  def parse!(der, ber: false)
40
58
  total_length, _data = do_parse(der, ber: ber)
41
59
  total_length
42
60
  end
43
61
 
44
- # @param [::Integer] level
62
+ # @param level [::Integer]
45
63
  # @return [String]
46
64
  def inspect(level=0)
47
65
  str = common_inspect(level)
@@ -66,6 +84,7 @@ module RASN1
66
84
 
67
85
  private
68
86
 
87
+ # @param level [Integer]
69
88
  def common_inspect(level)
70
89
  lvl = [0, level].max
71
90
  str = ' ' * lvl
@@ -77,6 +96,7 @@ module RASN1
77
96
  end
78
97
 
79
98
  # @private
99
+ # @!macro do_parse
80
100
  # @see Types::Base#do_parse
81
101
  def do_parse(der, ber: false)
82
102
  if der.empty?
@@ -96,6 +116,7 @@ module RASN1
96
116
  [total_length, real_value]
97
117
  end
98
118
 
119
+ # @return [String]
99
120
  def trace_any
100
121
  msg_type(no_id: true) << trace_data(value)
101
122
  end