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 +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
|
- - ">="
|