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.
- checksums.yaml +4 -4
- data/README.md +25 -10
- data/lib/rasn1/errors.rb +2 -2
- data/lib/rasn1/model/accel.rb +229 -0
- data/lib/rasn1/model.rb +125 -211
- data/lib/rasn1/tracer.rb +34 -14
- data/lib/rasn1/types/any.rb +24 -3
- data/lib/rasn1/types/base.rb +132 -36
- data/lib/rasn1/types/bit_string.rb +18 -5
- data/lib/rasn1/types/boolean.rb +14 -3
- data/lib/rasn1/types/choice.rb +39 -23
- data/lib/rasn1/types/constrained.rb +4 -3
- data/lib/rasn1/types/constructed.rb +4 -2
- data/lib/rasn1/types/enumerated.rb +9 -8
- data/lib/rasn1/types/generalized_time.rb +32 -13
- data/lib/rasn1/types/integer.rb +67 -11
- data/lib/rasn1/types/null.rb +7 -3
- data/lib/rasn1/types/numeric_string.rb +14 -2
- data/lib/rasn1/types/object_id.rb +15 -4
- data/lib/rasn1/types/octet_string.rb +3 -3
- data/lib/rasn1/types/primitive.rb +4 -0
- data/lib/rasn1/types/printable_string.rb +9 -2
- data/lib/rasn1/types/sequence.rb +7 -3
- data/lib/rasn1/types/sequence_of.rb +28 -8
- data/lib/rasn1/types/set_of.rb +1 -1
- data/lib/rasn1/types/utc_time.rb +7 -2
- data/lib/rasn1/types.rb +5 -5
- data/lib/rasn1/version.rb +1 -1
- data/lib/rasn1/wrapper.rb +38 -7
- data/lib/rasn1.rb +8 -7
- metadata +5 -4
data/lib/rasn1/model.rb
CHANGED
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
# Copyright (C) 2024 LemonTree55 <lenontree@proton.me>
|
|
7
7
|
# This program is published under MIT license.
|
|
8
8
|
|
|
9
|
+
require_relative 'model/accel'
|
|
10
|
+
|
|
9
11
|
module RASN1
|
|
10
12
|
# @abstract
|
|
11
13
|
# {Model} class is a base class to define ASN.1 models.
|
|
@@ -16,7 +18,8 @@ module RASN1
|
|
|
16
18
|
# room [0] IMPLICIT INTEGER OPTIONAL,
|
|
17
19
|
# house [1] EXPLICIT INTEGER DEFAULT 0
|
|
18
20
|
# }
|
|
19
|
-
#
|
|
21
|
+
#
|
|
22
|
+
# You may create your model like this:
|
|
20
23
|
# class Record < RASN1::Model
|
|
21
24
|
# sequence(:record,
|
|
22
25
|
# content: [integer(:id),
|
|
@@ -24,6 +27,15 @@ module RASN1
|
|
|
24
27
|
# integer(:house, explicit: 1, default: 0)])
|
|
25
28
|
# end
|
|
26
29
|
#
|
|
30
|
+
# You may also use block style definition:
|
|
31
|
+
# class Record < RASN1::Model
|
|
32
|
+
# sequence :record do
|
|
33
|
+
# integer :id
|
|
34
|
+
# integer :room, implicit: 0, optional: true
|
|
35
|
+
# integer :house, explicit: 1, default: 0
|
|
36
|
+
# end
|
|
37
|
+
# end
|
|
38
|
+
#
|
|
27
39
|
# In a model, each element must have a unique name.
|
|
28
40
|
#
|
|
29
41
|
# === Parse a DER-encoded string
|
|
@@ -47,10 +59,12 @@ module RASN1
|
|
|
47
59
|
# == Create a more complex model
|
|
48
60
|
# Models may be nested. For example:
|
|
49
61
|
# class Record2 < RASN1::Model
|
|
50
|
-
# sequence
|
|
51
|
-
#
|
|
52
|
-
#
|
|
62
|
+
# sequence :record2 do
|
|
63
|
+
# boolean :rented, default: false)
|
|
64
|
+
# model :a_record, Record
|
|
65
|
+
# end
|
|
53
66
|
# end
|
|
67
|
+
#
|
|
54
68
|
# Set values like this:
|
|
55
69
|
# record2 = Record2.new
|
|
56
70
|
# record2[:rented] = true
|
|
@@ -67,26 +81,37 @@ module RASN1
|
|
|
67
81
|
# this method.
|
|
68
82
|
# @author Sylvain Daubert
|
|
69
83
|
# @author adfoster-r7 ModelValidationError, track source location for dynamic class methods
|
|
84
|
+
# @since 0.17 block notation
|
|
70
85
|
class Model # rubocop:disable Metrics/ClassLength
|
|
71
86
|
# @private Base Element
|
|
72
|
-
BaseElem
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
87
|
+
class BaseElem
|
|
88
|
+
attr_accessor :name
|
|
89
|
+
attr_reader :proc, :content, :block
|
|
90
|
+
|
|
91
|
+
# @param name [String,Symbol]
|
|
92
|
+
# @param proc [Proc]
|
|
93
|
+
# @param content [Array,nil]
|
|
94
|
+
def initialize(name, proc, content, &block)
|
|
95
|
+
@name = name
|
|
96
|
+
@proc = proc
|
|
97
|
+
@content = content
|
|
98
|
+
@block = block
|
|
77
99
|
check_duplicates(content.map(&:name) + [name]) unless content.nil?
|
|
78
|
-
super
|
|
79
100
|
end
|
|
80
101
|
|
|
81
102
|
private
|
|
82
103
|
|
|
83
|
-
# @
|
|
104
|
+
# @param names [Array<String, Symbol>]
|
|
105
|
+
# @return [Array<String,Symbol>] The duplicate names found in the array
|
|
84
106
|
def find_all_duplicate_names(names)
|
|
85
107
|
names.group_by { |name| name }
|
|
86
108
|
.select { |_name, values| values.length > 1 }
|
|
87
109
|
.keys
|
|
88
110
|
end
|
|
89
111
|
|
|
112
|
+
# @param names [Array<String, Symbol>]
|
|
113
|
+
# @return [void]
|
|
114
|
+
# @raise [ModelValidationError] duplicate names in model definition
|
|
90
115
|
def check_duplicates(names)
|
|
91
116
|
duplicates = find_all_duplicate_names(names)
|
|
92
117
|
raise ModelValidationError, "Duplicate name #{duplicates.first} found" if duplicates.any?
|
|
@@ -107,184 +132,42 @@ module RASN1
|
|
|
107
132
|
# @private Sequence types
|
|
108
133
|
SEQUENCE_TYPES = [Types::Sequence, Types::SequenceOf, Types::Set, Types::SetOf].freeze
|
|
109
134
|
|
|
110
|
-
# Define helper methods to define models
|
|
111
|
-
module Accel
|
|
112
|
-
# @return [Hash]
|
|
113
|
-
attr_reader :options
|
|
114
|
-
|
|
115
|
-
# Use another model in this model
|
|
116
|
-
# @param [String,Symbol] name
|
|
117
|
-
# @param [Class] model_klass
|
|
118
|
-
# @return [Elem]
|
|
119
|
-
def model(name, model_klass)
|
|
120
|
-
@root = ModelElem.new(name, model_klass)
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
# Use a {Wrapper} around a {Types::Base} or a {Model} object
|
|
124
|
-
# @param [Types::Base,Model] element
|
|
125
|
-
# @param [Hash] options
|
|
126
|
-
# @return [WrapElem]
|
|
127
|
-
# @since 0.12
|
|
128
|
-
def wrapper(element, options={})
|
|
129
|
-
@root = WrapElem.new(element, options)
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
# Update options of root element.
|
|
133
|
-
# May be used when subclassing.
|
|
134
|
-
# class Model1 < RASN1::Model
|
|
135
|
-
# sequence :seq, implicit: 0,
|
|
136
|
-
# content: [bool(:bool), integer(:int)]
|
|
137
|
-
# end
|
|
138
|
-
#
|
|
139
|
-
# # same as Model1 but with implicit tag set to 1
|
|
140
|
-
# class Model2 < Model1
|
|
141
|
-
# root_options implicit: 1
|
|
142
|
-
# end
|
|
143
|
-
# @param [Hash] options
|
|
144
|
-
# @return [void]
|
|
145
|
-
# @since 0.12.0 may change name through +:name+
|
|
146
|
-
def root_options(options)
|
|
147
|
-
@options = options
|
|
148
|
-
return unless options.key?(:name)
|
|
149
|
-
|
|
150
|
-
@root = @root.dup
|
|
151
|
-
@root.name = options[:name]
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
# On inheritance, create +@root+ class variable
|
|
155
|
-
# @param [Class] klass
|
|
156
|
-
# @return [void]
|
|
157
|
-
def inherited(klass)
|
|
158
|
-
super
|
|
159
|
-
root = @root
|
|
160
|
-
klass.class_eval { @root = root }
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
# @private
|
|
164
|
-
# @param [String,Symbol] accel_name
|
|
165
|
-
# @param [Class] klass
|
|
166
|
-
# @since 0.11.0
|
|
167
|
-
# @since 0.12.0 track source location on error (adfoster-r7)
|
|
168
|
-
def define_type_accel_base(accel_name, klass)
|
|
169
|
-
singleton_class.class_eval <<-EVAL, __FILE__, __LINE__ + 1
|
|
170
|
-
def #{accel_name}(name, options={}) # def sequence(name, type, options)
|
|
171
|
-
options[:name] = name
|
|
172
|
-
proc = proc do |opts|
|
|
173
|
-
#{klass}.new(options.merge(opts)) # Sequence.new(options.merge(opts))
|
|
174
|
-
end
|
|
175
|
-
@root = BaseElem.new(name, proc, options[:content])
|
|
176
|
-
end
|
|
177
|
-
EVAL
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
# @private
|
|
181
|
-
# @param [String,Symbol] accel_name
|
|
182
|
-
# @param [Class] klass
|
|
183
|
-
# @since 0.11.0
|
|
184
|
-
# @since 0.12.0 track source location on error (adfoster-r7)
|
|
185
|
-
def define_type_accel_of(accel_name, klass)
|
|
186
|
-
singleton_class.class_eval <<-EVAL, __FILE__, __LINE__ + 1
|
|
187
|
-
def #{accel_name}_of(name, type, options={}) # def sequence_of(name, type, options)
|
|
188
|
-
options[:name] = name
|
|
189
|
-
proc = proc do |opts|
|
|
190
|
-
#{klass}.new(type, options.merge(opts)) # SequenceOf.new(type, options.merge(opts))
|
|
191
|
-
end
|
|
192
|
-
@root = BaseElem.new(name, proc, nil)
|
|
193
|
-
end
|
|
194
|
-
EVAL
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
# Define an accelarator to access a type in a model definition
|
|
198
|
-
# @param [String] accel_name
|
|
199
|
-
# @param [Class] klass class to instanciate
|
|
200
|
-
# @since 0.11.0
|
|
201
|
-
# @since 0.12.0 track source location on error (adfoster-r7)
|
|
202
|
-
def define_type_accel(accel_name, klass)
|
|
203
|
-
if klass < Types::SequenceOf
|
|
204
|
-
define_type_accel_of(accel_name, klass)
|
|
205
|
-
else
|
|
206
|
-
define_type_accel_base(accel_name, klass)
|
|
207
|
-
end
|
|
208
|
-
end
|
|
209
|
-
|
|
210
|
-
# @param [Symbol,String] name name of object in model
|
|
211
|
-
# @param [Hash] options
|
|
212
|
-
# @return [Elem]
|
|
213
|
-
# @note This method is named +objectid+ and not +object_id+ to not override
|
|
214
|
-
# +Object#object_id+.
|
|
215
|
-
# @see Types::ObjectId#initialize
|
|
216
|
-
def objectid(name, options={})
|
|
217
|
-
options[:name] = name
|
|
218
|
-
proc = proc { |opts| Types::ObjectId.new(options.merge(opts)) }
|
|
219
|
-
@root = BaseElem.new(name, proc, nil)
|
|
220
|
-
end
|
|
221
|
-
|
|
222
|
-
# @param [Symbol,String] name name of object in model
|
|
223
|
-
# @param [Hash] options
|
|
224
|
-
# @return [Elem]
|
|
225
|
-
# @see Types::Any#initialize
|
|
226
|
-
def any(name, options={})
|
|
227
|
-
options[:name] = name
|
|
228
|
-
proc = proc { |opts| Types::Any.new(options.merge(opts)) }
|
|
229
|
-
@root = BaseElem.new(name, proc, nil)
|
|
230
|
-
end
|
|
231
|
-
|
|
232
|
-
# Give type name (aka class name)
|
|
233
|
-
# @return [String]
|
|
234
|
-
def type
|
|
235
|
-
return @type if defined? @type
|
|
236
|
-
|
|
237
|
-
@type = self.to_s.gsub(/.*::/, '')
|
|
238
|
-
end
|
|
239
|
-
|
|
240
|
-
# Parse a DER/BER encoded string
|
|
241
|
-
# @param [String] str
|
|
242
|
-
# @param [Boolean] ber accept BER encoding or not
|
|
243
|
-
# @return [Model]
|
|
244
|
-
# @raise [ASN1Error] error on parsing
|
|
245
|
-
def parse(str, ber: false)
|
|
246
|
-
model = new
|
|
247
|
-
model.parse!(str, ber: ber)
|
|
248
|
-
model
|
|
249
|
-
end
|
|
250
|
-
end
|
|
251
|
-
|
|
252
135
|
extend Accel
|
|
253
136
|
|
|
254
137
|
# @!method sequence(name, options)
|
|
255
138
|
# @!scope class
|
|
256
|
-
# @param [Symbol,String] name
|
|
257
|
-
# @param [Hash]
|
|
139
|
+
# @param name [Symbol,String] name of object in model
|
|
140
|
+
# @param options [Hash]
|
|
258
141
|
# @return [Elem]
|
|
259
142
|
# @see Types::Sequence#initialize
|
|
260
143
|
# @!method set(name, options)
|
|
261
144
|
# @!scope class
|
|
262
|
-
# @param [Symbol,String] name
|
|
263
|
-
# @param [Hash]
|
|
145
|
+
# @param name [Symbol,String] name of object in model
|
|
146
|
+
# @param options [Hash]
|
|
264
147
|
# @return [Elem]
|
|
265
148
|
# @see Types::Set#initialize
|
|
266
149
|
# @!method choice(name, options)
|
|
267
150
|
# @!scope class
|
|
268
|
-
# @param [Symbol,String] name
|
|
269
|
-
# @param [Hash]
|
|
151
|
+
# @param name [Symbol,String] name of object in model
|
|
152
|
+
# @param options [Hash]
|
|
270
153
|
# @return [Elem]
|
|
271
154
|
# @see Types::Choice#initialize
|
|
272
155
|
%w[sequence set choice].each do |type|
|
|
273
|
-
self.
|
|
156
|
+
self.define_type_accel_container(type, Types.const_get(type.capitalize))
|
|
274
157
|
end
|
|
275
158
|
|
|
276
159
|
# @!method sequence_of(name, type, options)
|
|
277
160
|
# @!scope class
|
|
278
|
-
# @param [Symbol,String] name
|
|
279
|
-
# @param [Model, Types::Base] type
|
|
280
|
-
# @param [Hash]
|
|
161
|
+
# @param name [Symbol,String] name of object in model
|
|
162
|
+
# @param type [Model, Types::Base] type for SEQUENCE OF
|
|
163
|
+
# @param options [Hash]
|
|
281
164
|
# @return [Elem]
|
|
282
165
|
# @see Types::SequenceOf#initialize
|
|
283
166
|
# @!method set_of(name, type, options)
|
|
284
167
|
# @!scope class
|
|
285
|
-
# @param [Symbol,String] name
|
|
286
|
-
# @param [Model, Types::Base] type
|
|
287
|
-
# @param [Hash]
|
|
168
|
+
# @param name [Symbol,String] name of object in model
|
|
169
|
+
# @param type [Model, Types::Base] type for SET OF
|
|
170
|
+
# @param options [Hash]
|
|
288
171
|
# @return [Elem]
|
|
289
172
|
# @see Types::SetOf#initialize
|
|
290
173
|
%w[sequence set].each do |type|
|
|
@@ -293,80 +176,80 @@ module RASN1
|
|
|
293
176
|
|
|
294
177
|
# @!method boolean(name, options)
|
|
295
178
|
# @!scope class
|
|
296
|
-
# @param [Symbol,String] name
|
|
297
|
-
# @param [Hash]
|
|
179
|
+
# @param name [Symbol,String] name of object in model
|
|
180
|
+
# @param options [Hash]
|
|
298
181
|
# @return [Elem]
|
|
299
182
|
# @see Types::Boolean#initialize
|
|
300
183
|
# @!method integer(name, options)
|
|
301
184
|
# @!scope class
|
|
302
|
-
# @param [Symbol,String] name
|
|
303
|
-
# @param [Hash]
|
|
185
|
+
# @param name [Symbol,String] name of object in model
|
|
186
|
+
# @param options [Hash]
|
|
304
187
|
# @return [Elem]
|
|
305
188
|
# @see Types::Integer#initialize
|
|
306
189
|
# @!method bit_string(name, options)
|
|
307
190
|
# @!scope class
|
|
308
|
-
# @param [Symbol,String] name
|
|
309
|
-
# @param [Hash]
|
|
191
|
+
# @param name [Symbol,String] name of object in model
|
|
192
|
+
# @param options [Hash]
|
|
310
193
|
# @return [Elem]
|
|
311
194
|
# @see Types::BitString#initialize
|
|
312
195
|
# @!method bmp_string(name, options)
|
|
313
196
|
# @!scope class
|
|
314
|
-
# @param [Symbol,String] name
|
|
315
|
-
# @param [Hash]
|
|
197
|
+
# @param name [Symbol,String] name of object in model
|
|
198
|
+
# @param options [Hash]
|
|
316
199
|
# @return [Elem]
|
|
317
200
|
# @see Types::BmpString#initialize
|
|
318
201
|
# @!method octet_string(name, options)
|
|
319
202
|
# @!scope class
|
|
320
|
-
# @param [Symbol,String] name
|
|
321
|
-
# @param [Hash]
|
|
203
|
+
# @param name [Symbol,String] name of object in model
|
|
204
|
+
# @param options [Hash]
|
|
322
205
|
# @return [Elem]
|
|
323
206
|
# @see Types::OctetString#initialize
|
|
324
207
|
# @!method null(name, options)
|
|
325
208
|
# @!scope class
|
|
326
|
-
# @param [Symbol,String] name
|
|
327
|
-
# @param [Hash]
|
|
209
|
+
# @param name [Symbol,String] name of object in model
|
|
210
|
+
# @param options [Hash]
|
|
328
211
|
# @return [Elem]
|
|
329
212
|
# @see Types::Null#initialize
|
|
330
213
|
# @!method enumerated(name, options)
|
|
331
214
|
# @!scope class
|
|
332
|
-
# @param [Symbol,String] name
|
|
333
|
-
# @param [Hash]
|
|
215
|
+
# @param name [Symbol,String] name of object in model
|
|
216
|
+
# @param options [Hash]
|
|
334
217
|
# @return [Elem]
|
|
335
218
|
# @see Types::Enumerated#initialize
|
|
336
219
|
# @!method universal_string(name, options)
|
|
337
220
|
# @!scope class
|
|
338
|
-
# @param [Symbol,String] name
|
|
339
|
-
# @param [Hash]
|
|
221
|
+
# @param name [Symbol,String] name of object in model
|
|
222
|
+
# @param options [Hash]
|
|
340
223
|
# @return [Elem]
|
|
341
224
|
# @see Types::UniversalString#initialize
|
|
342
225
|
# @!method utf8_string(name, options)
|
|
343
226
|
# @!scope class
|
|
344
|
-
# @param [Symbol,String] name
|
|
345
|
-
# @param [Hash]
|
|
227
|
+
# @param name [Symbol,String] name of object in model
|
|
228
|
+
# @param options [Hash]
|
|
346
229
|
# @return [Elem]
|
|
347
230
|
# @see Types::Utf8String#initialize
|
|
348
231
|
# @!method numeric_string(name, options)
|
|
349
232
|
# @!scope class
|
|
350
|
-
# @param [Symbol,String] name
|
|
351
|
-
# @param [Hash]
|
|
233
|
+
# @param name [Symbol,String] name of object in model
|
|
234
|
+
# @param options [Hash]
|
|
352
235
|
# @return [Elem]
|
|
353
236
|
# @see Types::NumericString#initialize
|
|
354
237
|
# @!method printable_string(name, options)
|
|
355
238
|
# @!scope class
|
|
356
|
-
# @param [Symbol,String] name
|
|
357
|
-
# @param [Hash]
|
|
239
|
+
# @param name [Symbol,String] name of object in model
|
|
240
|
+
# @param options [Hash]
|
|
358
241
|
# @return [Elem]
|
|
359
242
|
# @see Types::PrintableString#initialize
|
|
360
243
|
# @!method visible_string(name, options)
|
|
361
244
|
# @!scope class
|
|
362
|
-
# @param [Symbol,String] name
|
|
363
|
-
# @param [Hash]
|
|
245
|
+
# @param name [Symbol,String] name of object in model
|
|
246
|
+
# @param options [Hash]
|
|
364
247
|
# @return [Elem]
|
|
365
248
|
# @see Types::VisibleString#initialize
|
|
366
249
|
# @!method ia5_string(name, options)
|
|
367
250
|
# @!scope class
|
|
368
|
-
# @param [Symbol,String] name
|
|
369
|
-
# @param [Hash]
|
|
251
|
+
# @param name [Symbol,String] name of object in model
|
|
252
|
+
# @param options [Hash]
|
|
370
253
|
# @return [Elem]
|
|
371
254
|
# @see Types::IA5String#initialize
|
|
372
255
|
Types.primitives.each do |prim|
|
|
@@ -380,7 +263,7 @@ module RASN1
|
|
|
380
263
|
attr_reader :root
|
|
381
264
|
|
|
382
265
|
# Create a new instance of a {Model}
|
|
383
|
-
# @param [Hash]
|
|
266
|
+
# @param args [Hash]
|
|
384
267
|
def initialize(args={})
|
|
385
268
|
@elements = {}
|
|
386
269
|
generate_root(args)
|
|
@@ -390,11 +273,11 @@ module RASN1
|
|
|
390
273
|
|
|
391
274
|
# @overload [](name)
|
|
392
275
|
# Access an element of the model by its name
|
|
393
|
-
# @param [Symbol]
|
|
276
|
+
# @param name [Symbol]
|
|
394
277
|
# @return [Model, Types::Base, Wrapper]
|
|
395
278
|
# @overload [](idx)
|
|
396
279
|
# Access an element of root element by its index. Root element must be a {Types::Sequence} or {Types::SequenceOf}.
|
|
397
|
-
# @param [Integer]
|
|
280
|
+
# @param idx [Integer]
|
|
398
281
|
# @return [Model, Types::Base, Wrapper]
|
|
399
282
|
def [](name_or_idx)
|
|
400
283
|
case name_or_idx
|
|
@@ -409,8 +292,8 @@ module RASN1
|
|
|
409
292
|
end
|
|
410
293
|
|
|
411
294
|
# Set value of element +name+. Element should be a {Types::Base}.
|
|
412
|
-
# @param [String,Symbol]
|
|
413
|
-
# @param [Object]
|
|
295
|
+
# @param name [String,Symbol]
|
|
296
|
+
# @param value [Object]
|
|
414
297
|
# @return [Object] value
|
|
415
298
|
def []=(name, value)
|
|
416
299
|
# Here, use #[] to force generation for lazy elements
|
|
@@ -420,7 +303,8 @@ module RASN1
|
|
|
420
303
|
end
|
|
421
304
|
|
|
422
305
|
# clone @elements and initialize @root from this new @element.
|
|
423
|
-
|
|
306
|
+
# @return [void]
|
|
307
|
+
def initialize_copy(*)
|
|
424
308
|
@elements = @elements.clone
|
|
425
309
|
@root = @elements[@root_name]
|
|
426
310
|
end
|
|
@@ -455,8 +339,8 @@ module RASN1
|
|
|
455
339
|
end
|
|
456
340
|
|
|
457
341
|
# Parse a DER/BER encoded string, and modify object in-place.
|
|
458
|
-
# @param [String]
|
|
459
|
-
# @param [Boolean]
|
|
342
|
+
# @param der [String]
|
|
343
|
+
# @param ber [Boolean] accept BER encoding or not
|
|
460
344
|
# @return [Integer] number of parsed bytes
|
|
461
345
|
# @raise [ASN1Error] error on parsing
|
|
462
346
|
def parse!(der, ber: false)
|
|
@@ -464,6 +348,7 @@ module RASN1
|
|
|
464
348
|
end
|
|
465
349
|
|
|
466
350
|
# @private
|
|
351
|
+
# @!macro do_parse
|
|
467
352
|
# @see Types::Base#do_parse
|
|
468
353
|
def do_parse(der, ber: false)
|
|
469
354
|
root.do_parse(der, ber: ber)
|
|
@@ -474,8 +359,8 @@ module RASN1
|
|
|
474
359
|
# @return [Object,nil]
|
|
475
360
|
# @overload value(name, *args)
|
|
476
361
|
# Direct access to the value of +name+ (nested) element of model.
|
|
477
|
-
# @param [String,Symbol]
|
|
478
|
-
# @param [Array<Integer,String,Symbol>]
|
|
362
|
+
# @param name [String,Symbol]
|
|
363
|
+
# @param args [Array<Integer,String,Symbol>] more argument to access element. May be
|
|
479
364
|
# used to access content of a SequenceOf or a SetOf
|
|
480
365
|
# @return [Object,nil]
|
|
481
366
|
# @return [Object,nil]
|
|
@@ -508,10 +393,11 @@ module RASN1
|
|
|
508
393
|
end
|
|
509
394
|
end
|
|
510
395
|
|
|
511
|
-
# Return a hash image of model
|
|
512
|
-
# @return [Hash]
|
|
513
396
|
# Delegate some methods to root element
|
|
514
|
-
# @param [Symbol]
|
|
397
|
+
# @param meth [Symbol]
|
|
398
|
+
# @param args [Array]
|
|
399
|
+
# @param kwargs [Hash]
|
|
400
|
+
# @return [Object]
|
|
515
401
|
def method_missing(meth, *args, **kwargs)
|
|
516
402
|
if root.respond_to?(meth)
|
|
517
403
|
root.send(meth, *args, **kwargs)
|
|
@@ -520,18 +406,20 @@ module RASN1
|
|
|
520
406
|
end
|
|
521
407
|
end
|
|
522
408
|
|
|
409
|
+
# @param meth [Symbol]
|
|
523
410
|
# @return [Boolean]
|
|
524
411
|
def respond_to_missing?(meth, *)
|
|
525
412
|
root.respond_to?(meth) || super
|
|
526
413
|
end
|
|
527
414
|
|
|
415
|
+
# @param level [Integer]
|
|
528
416
|
# @return [String]
|
|
529
417
|
def inspect(level=0)
|
|
530
418
|
"#{' ' * level}(#{type}) #{root.inspect(-level)}"
|
|
531
419
|
end
|
|
532
420
|
|
|
533
421
|
# Objects are equal if they have same class AND same DER
|
|
534
|
-
# @param [Base]
|
|
422
|
+
# @param other [Base]
|
|
535
423
|
# @return [Boolean]
|
|
536
424
|
def ==(other)
|
|
537
425
|
(other.class == self.class) && (other.to_der == self.to_der)
|
|
@@ -540,7 +428,7 @@ module RASN1
|
|
|
540
428
|
protected
|
|
541
429
|
|
|
542
430
|
# Initialize model elements from +args+
|
|
543
|
-
# @param [Hash,Array]
|
|
431
|
+
# @param args [Hash,Array]
|
|
544
432
|
# @return [void]
|
|
545
433
|
def lazy_initialize(args)
|
|
546
434
|
case args
|
|
@@ -552,7 +440,7 @@ module RASN1
|
|
|
552
440
|
end
|
|
553
441
|
|
|
554
442
|
# Initialize an element from a hash
|
|
555
|
-
# @param [Hash]
|
|
443
|
+
# @param args [Hash]
|
|
556
444
|
# @return [void]
|
|
557
445
|
def lazy_initialize_hash(args)
|
|
558
446
|
args.each do |name, value|
|
|
@@ -568,7 +456,7 @@ module RASN1
|
|
|
568
456
|
end
|
|
569
457
|
|
|
570
458
|
# Initialize an sequence element from an array
|
|
571
|
-
# @param [Array]
|
|
459
|
+
# @param ary [Array]
|
|
572
460
|
# @return [void]
|
|
573
461
|
def lazy_initialize_array(ary)
|
|
574
462
|
raise Error, 'Only sequence types may be initialized with an array' unless SEQUENCE_TYPES.any? { |klass| root.is_a?(klass) }
|
|
@@ -579,7 +467,7 @@ module RASN1
|
|
|
579
467
|
end
|
|
580
468
|
|
|
581
469
|
# Give a (nested) element from its name
|
|
582
|
-
# @param [String, Symbol]
|
|
470
|
+
# @param name [String, Symbol]
|
|
583
471
|
# @return [Model, Types::Base, nil]
|
|
584
472
|
def by_name(name)
|
|
585
473
|
elt = self[name]
|
|
@@ -597,9 +485,11 @@ module RASN1
|
|
|
597
485
|
|
|
598
486
|
private
|
|
599
487
|
|
|
488
|
+
# @param args [Hash]
|
|
489
|
+
# @return [void]
|
|
600
490
|
def generate_root(args)
|
|
601
491
|
opts = args.slice(:name, :explicit, :implicit, :optional, :class, :default, :constructed, :tag_value)
|
|
602
|
-
root = self.class.
|
|
492
|
+
root = self.class.root
|
|
603
493
|
root_options = self.class.options || {}
|
|
604
494
|
root_options.merge!(opts)
|
|
605
495
|
@root_name = args[:name] || root.name
|
|
@@ -607,6 +497,9 @@ module RASN1
|
|
|
607
497
|
@elements[@root_name] = @root
|
|
608
498
|
end
|
|
609
499
|
|
|
500
|
+
# @param elt [BaseElem, ModelElem,WrapElem]
|
|
501
|
+
# @param opts [Hash]
|
|
502
|
+
# @return[Types::Base,Model,Wrapper]
|
|
610
503
|
def generate_element(elt, opts={})
|
|
611
504
|
case elt
|
|
612
505
|
when BaseElem
|
|
@@ -619,6 +512,9 @@ module RASN1
|
|
|
619
512
|
end
|
|
620
513
|
end
|
|
621
514
|
|
|
515
|
+
# @param elt [WrapElem]
|
|
516
|
+
# @param opts [Hash]
|
|
517
|
+
# @return[Wrapper]
|
|
622
518
|
def generate_wrapper_element(elt, opts)
|
|
623
519
|
wrapped = elt.element.is_a?(ModelElem) ? elt.element.klass : generate_element(elt.element)
|
|
624
520
|
options = elt.options.merge(opts)
|
|
@@ -629,6 +525,9 @@ module RASN1
|
|
|
629
525
|
wrapper
|
|
630
526
|
end
|
|
631
527
|
|
|
528
|
+
# @param elt [BaseElem]
|
|
529
|
+
# @param opts [Hash]
|
|
530
|
+
# @return[Types::Base]
|
|
632
531
|
def generate_base_element(elt, opts)
|
|
633
532
|
element = elt.proc.call(opts)
|
|
634
533
|
return element if elt.content.nil?
|
|
@@ -643,6 +542,8 @@ module RASN1
|
|
|
643
542
|
# @author sdaubert
|
|
644
543
|
# @author lemontree55
|
|
645
544
|
# @author adfoster-r7
|
|
545
|
+
# @param element [Model, Types::Base, Wrapper,nil]
|
|
546
|
+
# @return [Hash]
|
|
646
547
|
def private_to_h(element=nil) # rubocop:disable Metrics/CyclomaticComplexity
|
|
647
548
|
my_element = element || root
|
|
648
549
|
value = case my_element
|
|
@@ -666,6 +567,8 @@ module RASN1
|
|
|
666
567
|
end
|
|
667
568
|
end
|
|
668
569
|
|
|
570
|
+
# @param elt [Model]
|
|
571
|
+
# @return [Hash]
|
|
669
572
|
def model_to_h(elt)
|
|
670
573
|
hsh = elt.to_h
|
|
671
574
|
if root.is_a?(Types::Choice)
|
|
@@ -675,6 +578,8 @@ module RASN1
|
|
|
675
578
|
end
|
|
676
579
|
end
|
|
677
580
|
|
|
581
|
+
# @param elt [Types::SequenceOf]
|
|
582
|
+
# @return [Array<Hash>]
|
|
678
583
|
def sequence_of_to_h(elt)
|
|
679
584
|
if elt.of_type < Model
|
|
680
585
|
elt.value&.map { |el| el.to_h.values.first }
|
|
@@ -683,6 +588,8 @@ module RASN1
|
|
|
683
588
|
end
|
|
684
589
|
end
|
|
685
590
|
|
|
591
|
+
# @param seq [Types::Sequence]
|
|
592
|
+
# @return [Hash]
|
|
686
593
|
def sequence_to_h(seq)
|
|
687
594
|
ary = seq.value&.map do |el|
|
|
688
595
|
next if el.optional? && el.value.nil?
|
|
@@ -699,6 +606,9 @@ module RASN1
|
|
|
699
606
|
ary.compact.to_h
|
|
700
607
|
end
|
|
701
608
|
|
|
609
|
+
# @param elt [Types::Choice]
|
|
610
|
+
# @return [Hash]
|
|
611
|
+
# @raise [ChoiceError] no chosen element
|
|
702
612
|
def choice_to_h(elt)
|
|
703
613
|
raise ChoiceError.new(elt) if elt.chosen.nil?
|
|
704
614
|
|
|
@@ -706,10 +616,14 @@ module RASN1
|
|
|
706
616
|
{ chosen.name => private_to_h(chosen) }
|
|
707
617
|
end
|
|
708
618
|
|
|
619
|
+
# @param key [String,Symbol]
|
|
620
|
+
# @return [Symbol]
|
|
709
621
|
def unwrap_keyname(key)
|
|
710
622
|
key.to_s.delete_suffix('_wrapper').to_sym
|
|
711
623
|
end
|
|
712
624
|
|
|
625
|
+
# @param wrap [Wrapper]
|
|
626
|
+
# @return [Hash]
|
|
713
627
|
def wrapper_to_h(wrap)
|
|
714
628
|
el = wrap.element
|
|
715
629
|
case el
|