rasn1 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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
  - - ">="