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 +4 -4
- data/lib/rasn1/model.rb +15 -7
- data/lib/rasn1/types/any.rb +21 -2
- data/lib/rasn1/types/base.rb +12 -0
- data/lib/rasn1/types/bit_string.rb +6 -1
- data/lib/rasn1/types/choice.rb +11 -0
- data/lib/rasn1/types/constructed.rb +0 -1
- data/lib/rasn1/types/sequence.rb +22 -2
- data/lib/rasn1/types/sequence_of.rb +60 -41
- data/lib/rasn1/version.rb +1 -1
- data/rasn1.gemspec +2 -3
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e9f8ffeb57fd641930cbe2e820c903102ed404e6
|
4
|
+
data.tar.gz: 8d214577ea3085f99a96926e9e26a81f3148e262
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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
|
-
|
332
|
-
|
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
|
data/lib/rasn1/types/any.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
module RASN1
|
2
2
|
module Types
|
3
3
|
|
4
|
-
# ASN.1 ANY:
|
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
|
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
|
data/lib/rasn1/types/base.rb
CHANGED
@@ -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
|
-
|
data/lib/rasn1/types/choice.rb
CHANGED
@@ -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
|
data/lib/rasn1/types/sequence.rb
CHANGED
@@ -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
|
-
|
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
|
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
|
24
|
-
# seqof
|
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
|
36
|
-
# seqof
|
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
|
-
|
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
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
@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
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.
|
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
|
+
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-
|
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: :
|
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.
|
134
|
+
version: 2.2.0
|
135
135
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
136
136
|
requirements:
|
137
137
|
- - ">="
|