rasn1 0.4.0 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1db3f68204210c681a17f1d0a367d680906997b8
4
- data.tar.gz: 8fec0011426f3b19dd61ef1ba57d904e0de14596
3
+ metadata.gz: e9f8ffeb57fd641930cbe2e820c903102ed404e6
4
+ data.tar.gz: 8d214577ea3085f99a96926e9e26a81f3148e262
5
5
  SHA512:
6
- metadata.gz: d1df79db814d23882b371fbe165c5966e19b75f17bacd9b97f2f9ad8b6dad967e060f01eff201389192562c54ad011ead484a1f0ce941dce33cdf081cc19978d
7
- data.tar.gz: 7e4184159aee769387c5ecb62f6d1b02e48f477780597cc2dcd50d8bf6f1be93613e8319c90fdfdf4967e1f4f98ca9187c06911fa396fc229d40e4c461c12e3f
6
+ metadata.gz: c6a96e1e65a1fccaa036b984933fda1b3f5c43d03c0a6b05fb262b3b2a3a1cf6aebb4de0e87bf38455ea726f1a21ec793e307dfe24dd94b202ef0428b7db79dd
7
+ data.tar.gz: cbad3dcc907ef35b8bb6689fa4d35b04797c2374f7e9a7f9b26349b0da3bdb99ec71b7262c3018104175d64b9d3922bd0d8564b194f2616f3a02c60415ea631b
data/lib/rasn1/model.rb CHANGED
@@ -260,8 +260,16 @@ module RASN1
260
260
  end
261
261
  end
262
262
 
263
+ # @return [String]
263
264
  def inspect(level=0)
264
- ' ' * level + "#{type} #{root.inspect(-level)}"
265
+ ' ' * level + "#{@root} (#{type}) #{root.inspect(-level)}"
266
+ end
267
+
268
+ # Objects are equal if they have same class AND same DER
269
+ # @param [Base] other
270
+ # @return [Boolean]
271
+ def==(other)
272
+ (other.class == self.class) && (other.to_der == self.to_der)
265
273
  end
266
274
 
267
275
  private
@@ -321,18 +329,18 @@ module RASN1
321
329
  end
322
330
 
323
331
  def private_to_h(element)
324
- if element.value.is_a? Array
332
+ if element.is_a?(Types::SequenceOf) or
333
+ (element.is_a?(Model) and element.root.is_a?(Types::SequenceOf))
334
+ element.value.map { |el| private_to_h(el) }
335
+ elsif element.value.is_a? Array
325
336
  h = {}
326
337
  element.value.each do |subel|
327
338
  case subel
328
339
  when Types::Sequence, Types::Set
329
340
  h[subel.name] = private_to_h(subel)
330
341
  when Model
331
- h[@elements.key(subel)] = subel.to_h[subel.name]
332
- when Hash, Array
333
- # Array of Hash for SequenceOf and SetOf
334
- # Array of Array of... of Hash are nested SequenceOf or SetOf
335
- return element.value
342
+ this_name = @elements.key(subel) || element.name
343
+ h[this_name] = subel.to_h[subel.name]
336
344
  else
337
345
  next if subel.value.nil? and subel.optional?
338
346
  h[subel.name] = subel.value
@@ -1,7 +1,9 @@
1
1
  module RASN1
2
2
  module Types
3
3
 
4
- # ASN.1 ANY: accpets any types
4
+ # ASN.1 ANY: accepts any types
5
+ #
6
+ # If `any#value` is `nil`, `any` will be encoded as a {Null} object.
5
7
  # @author Sylvain Daubert
6
8
  class Any < Base
7
9
 
@@ -10,12 +12,15 @@ module RASN1
10
12
  case @value
11
13
  when Base, Model
12
14
  @value.to_der
15
+ when nil
16
+ Null.new(@name).to_der
13
17
  else
14
18
  @value.to_s
15
19
  end
16
20
  end
17
21
 
18
- # Parse a DER string. This method updates object: {#value} will a DER string.
22
+ # Parse a DER string. This method updates object: {#value} will be a DER
23
+ # string.
19
24
  # @param [String] der DER string
20
25
  # @param [Boolean] ber if +true+, accept BER encoding
21
26
  # @return [Integer] total number of parsed bytes
@@ -24,6 +29,20 @@ module RASN1
24
29
  @value = der[0, total_length]
25
30
  total_length
26
31
  end
32
+
33
+ def inspect(level=0)
34
+ str = ''
35
+ str << ' ' * level if level > 0
36
+ if @value.nil?
37
+ str << "#{name} (ANY) NULL"
38
+ elsif @value.is_a?(OctetString)
39
+ str << "#{name} (ANY) #{@value.type}: #{value.value.inspect}"
40
+ elsif @value.class < Base
41
+ str << "#{name} (ANY) #{@value.type}: #{value.value}"
42
+ else
43
+ str << "#{name} (ANY) #{value.to_s.inspect}"
44
+ end
45
+ end
27
46
  end
28
47
  end
29
48
  end
@@ -97,6 +97,11 @@ module RASN1
97
97
  # Used by +#dup+ and +#clone+. Deep copy @value.
98
98
  def initialize_copy(other)
99
99
  @value = @value.nil? ? nil : @value.dup
100
+ begin
101
+ @default = @default.dup
102
+ rescue TypeError => ex
103
+ raise unless ex.message =~ /can't (dup|clone)/
104
+ end
100
105
  end
101
106
 
102
107
  # Get value or default value
@@ -206,6 +211,13 @@ module RASN1
206
211
  str << "#{name} #{type}: #{value}"
207
212
  end
208
213
 
214
+ # Objects are equal if they have same class AND same DER
215
+ # @param [Base] other
216
+ # @return [Boolean]
217
+ def ==(other)
218
+ (other.class == self.class) && (other.to_der == self.to_der)
219
+ end
220
+
209
221
  private
210
222
 
211
223
  def set_options(options)
@@ -27,6 +27,12 @@ module RASN1
27
27
  end
28
28
  end
29
29
 
30
+ def inspect(level=0)
31
+ str = ''
32
+ str << ' ' * level if level > 0
33
+ str << "#{name} #{type}: #{value.inspect} (bit length: #{bit_length})"
34
+ end
35
+
30
36
  private
31
37
 
32
38
  def build_tag?
@@ -67,4 +73,3 @@ module RASN1
67
73
  end
68
74
  end
69
75
  end
70
-
@@ -90,6 +90,17 @@ module RASN1
90
90
  raise ASN1Error, "CHOICE #@name: no type matching #{der.inspect}" unless parsed
91
91
  end
92
92
 
93
+ def inspect(level=0)
94
+ str = ''
95
+ str << ' ' * level if level > 0
96
+ str << "#{name} #{type}: "
97
+ if @chosen.nil?
98
+ str << 'not chosen!'
99
+ else
100
+ str << @value[@chosen].inspect(level)
101
+ end
102
+ end
103
+
93
104
  private
94
105
 
95
106
  def check_chosen
@@ -20,7 +20,6 @@ module RASN1
20
20
  @value.each do |item|
21
21
  case item
22
22
  when Base, Model
23
- p item
24
23
  next if item.optional? and item.value.nil?
25
24
  str << ' ' * level + "#{item.inspect(level)}\n"
26
25
  else
@@ -27,6 +27,27 @@ module RASN1
27
27
  class Sequence < Constructed
28
28
  TAG = 0x10
29
29
 
30
+ # @param [Symbol, String] name name for this tag in grammar
31
+ # @param [Hash] options
32
+ # @option options [Symbol] :class ASN.1 tag class. Default value is +:universal+.
33
+ # If +:explicit+ or +:implicit:+ is defined, default value is +:context+.
34
+ # @option options [::Boolean] :optional define this tag as optional. Default
35
+ # is +false+
36
+ # @option options [Object] :default default value for DEFAULT tag
37
+ # @option options [Object] :value value to set (default is +[]+)
38
+ # @option options [::Integer] :implicit define an IMPLICIT tagged type
39
+ # @option options [::Integer] :explicit define an EXPLICIT tagged type
40
+ # @option options [::Boolean] :constructed if +true+, set type as constructed.
41
+ # May only be used when +:explicit+ is defined, else it is discarded.
42
+ def initialize(name, options={})
43
+ super(name, { value: [] }.merge(options))
44
+ end
45
+
46
+ def initialize_copy(other)
47
+ super
48
+ @value.map! { |v| v.dup }
49
+ end
50
+
30
51
  private
31
52
 
32
53
  def value_to_der
@@ -39,8 +60,7 @@ module RASN1
39
60
  end
40
61
 
41
62
  def der_to_value(der, ber:false)
42
- case @value
43
- when Array
63
+ if @value.is_a?(Array) and !@value.empty?
44
64
  nb_bytes = 0
45
65
  @value.each do |element|
46
66
  nb_bytes += element.parse!(der[nb_bytes..-1])
@@ -12,7 +12,7 @@ module RASN1
12
12
  # # Create a SEQUENCE OF INTEGER
13
13
  # seqof = RASN1::Types::SequenceOf.new(:record, RASN1::Types::Integer)
14
14
  # # Set integer values
15
- # seqof.value = [1, 2, 3, 4]
15
+ # seqof.value << [1, 2, 3, 4]
16
16
  #
17
17
  # == Use with {Constructed} types
18
18
  # SEQUENCE OF may be used to create sequence of composed types. For example:
@@ -20,8 +20,8 @@ module RASN1
20
20
  # commposed_type.value = [RASN1::Types::Integer(:id),
21
21
  # RASN1::Types::OctetString(:data)]
22
22
  # seqof = RASN1::SequenceOf.new(:comp, composed_type)
23
- # seqof.value << [0, 'data0']
24
- # seqof.value << [1, 'data1']
23
+ # seqof << [0, 'data0']
24
+ # seqof << [1, 'data1']
25
25
  #
26
26
  # == Use with {Model}
27
27
  # SEQUENCE OF may also be used with a Model type:
@@ -32,12 +32,17 @@ module RASN1
32
32
  #
33
33
  # seqof = RASN1::Types::SequenceOf.new(:record, MyModel)
34
34
  # # set values
35
- # seqof.value << { bool: true, int: 12 }
36
- # seqof.value << { bool: false, int: 65535 }
35
+ # seqof << { bool: true, int: 12 }
36
+ # seqof << { bool: false, int: 65535 }
37
37
  # # Generate DER string
38
38
  # der = seqof.to_der # => String
39
39
  # # parse
40
40
  # seqof.parse! der
41
+ #
42
+ # After parsing, a SEQUENCE OF may be accessed as an Array:
43
+ # seqof[0] # => MyModel
44
+ # seqof[0][:bool].value # => true
45
+ # seqof[0][:int].value # => 12
41
46
  # @author Sylvain Daubert
42
47
  class SequenceOf < Constructed
43
48
  TAG = Sequence::TAG
@@ -54,6 +59,46 @@ module RASN1
54
59
  @value = []
55
60
  end
56
61
 
62
+ def initialize_copy(other)
63
+ super
64
+ @of_type = @of_type.dup
65
+ @value.map! { |v| v.dup }
66
+ end
67
+
68
+ # Add an item to SEQUENCE OF
69
+ # @param [Array,Hash, Model]
70
+ def <<(obj)
71
+ if of_type_class < Primitive
72
+ raise ASN1Error, 'object to add should be an Array' unless obj.is_a?(Array)
73
+ @value += obj.map { |item| @of_type.new(nil, value: item) }
74
+ elsif composed_of_type?
75
+ raise ASN1Error, 'object to add should be an Array' unless obj.is_a?(Array)
76
+ new_value = of_type_class.new(@of_type.name, value: [])
77
+ @of_type.value.each_with_index do |type, i|
78
+ type2 = type.dup
79
+ type2.value = obj[i]
80
+ new_value.value << type2
81
+ end
82
+ @value << new_value
83
+ elsif of_type_class < Model
84
+ case obj
85
+ when Hash
86
+ @value << @of_type.new(obj)
87
+ when of_type_class
88
+ @value << obj
89
+ else
90
+ raise ASN1Error, "object to add should be a #{of_type_class} or a Hash"
91
+ end
92
+ end
93
+ end
94
+
95
+ # Get element of index +idx+
96
+ # @param [Integer] idx
97
+ # @return [Base]
98
+ def [](idx)
99
+ @value[idx]
100
+ end
101
+
57
102
  def inspect(level=0)
58
103
  str = ''
59
104
  str << ' ' * level if level > 0
@@ -87,34 +132,7 @@ module RASN1
87
132
  end
88
133
 
89
134
  def value_to_der
90
- if composed_of_type?
91
- @value.map do |ary|
92
- s = of_type_class.new(@of_type.name)
93
- sval = []
94
- @of_type.value.each_with_index do |type, i|
95
- type2 = type.dup
96
- type2.value = ary[i]
97
- sval << type2
98
- end
99
- s.value = sval
100
- s.to_der
101
- end.join
102
- elsif of_type_class < Model
103
- if of_type_class.new.root.is_a? SequenceOf
104
- @value.map do |ary|
105
- model = of_type_class.new
106
- model.root.value = ary
107
- model.to_der
108
- end.join
109
- else
110
- @value.map do |hsh|
111
- model = of_type_class.new(hsh)
112
- model.to_der
113
- end.join
114
- end
115
- else
116
- @value.map { |v| of_type_class.new(:t, value: v).to_der }.join
117
- end
135
+ @value.map { |v| v.to_der }.join
118
136
  end
119
137
 
120
138
  def der_to_value(der, ber:false)
@@ -130,15 +148,16 @@ module RASN1
130
148
  of_type_class.new(:t)
131
149
  end
132
150
  nb_bytes += type.parse!(der[nb_bytes, der.length])
133
- value = if composed_of_type?
134
- type.value.map { |obj| obj.value }
135
- elsif of_type_class < Model
136
- type.to_h[type.to_h.keys.first]
137
- else
138
- type.value
139
- end
140
- @value << value
151
+ #value = if composed_of_type?
152
+ # type.value.map { |obj| obj.value }
153
+ # elsif of_type_class < Model
154
+ # type.to_h[type.to_h.keys.first]
155
+ # else
156
+ # type.value
157
+ # end
158
+ @value << type
141
159
  end
160
+ #puts "#{name}: #{@value.inspect}"
142
161
  end
143
162
 
144
163
  def explicit_type
data/lib/rasn1/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module RASN1
2
- VERSION = "0.4.0"
2
+ VERSION = "0.5.0"
3
3
  end
data/rasn1.gemspec CHANGED
@@ -19,10 +19,9 @@ Gem::Specification.new do |spec|
19
19
  end
20
20
  spec.require_paths = ['lib']
21
21
 
22
- spec.required_ruby_version = '>= 2.1.0'
23
-
24
- spec.add_dependency 'yard', '~>0.9'
22
+ spec.required_ruby_version = '>= 2.2.0'
25
23
 
24
+ spec.add_development_dependency 'yard', '~>0.9'
26
25
  spec.add_development_dependency 'bundler', '~> 1.13'
27
26
  spec.add_development_dependency 'rake', '~> 10.0'
28
27
  spec.add_development_dependency 'rspec', '~> 3.0'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rasn1
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sylvain Daubert
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-12-03 00:00:00.000000000 Z
11
+ date: 2017-12-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: yard
@@ -17,7 +17,7 @@ dependencies:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0.9'
20
- type: :runtime
20
+ type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
@@ -131,7 +131,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
131
131
  requirements:
132
132
  - - ">="
133
133
  - !ruby/object:Gem::Version
134
- version: 2.1.0
134
+ version: 2.2.0
135
135
  required_rubygems_version: !ruby/object:Gem::Requirement
136
136
  requirements:
137
137
  - - ">="