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/tracer.rb
CHANGED
|
@@ -14,40 +14,48 @@ module RASN1
|
|
|
14
14
|
# @return [Integer]
|
|
15
15
|
attr_accessor :tracing_level
|
|
16
16
|
|
|
17
|
+
# @private
|
|
18
|
+
# Classes to trace
|
|
17
19
|
TRACED_CLASSES = [Types::Any, Types::Choice, Types::Sequence, Types::SequenceOf, Types::Base].freeze
|
|
18
20
|
|
|
19
|
-
# @param [IO] io
|
|
21
|
+
# @param io [IO] io to use to put traces
|
|
20
22
|
def initialize(io)
|
|
21
23
|
@io = io
|
|
22
24
|
@tracing_level = 0
|
|
23
25
|
end
|
|
24
26
|
|
|
25
27
|
# Puts +msg+ onto {#io}.
|
|
26
|
-
# @param [String]
|
|
28
|
+
# @param msg [String]
|
|
27
29
|
# @return [void]
|
|
28
30
|
def trace(msg)
|
|
29
31
|
@io.puts(indent << msg)
|
|
30
32
|
end
|
|
31
33
|
|
|
32
34
|
# Return identation for given +level+. If +nil+, use {#tracing_level}.
|
|
33
|
-
# @param [Integer,nil]
|
|
35
|
+
# @param level [Integer,nil]
|
|
34
36
|
# @return [String]
|
|
35
37
|
def indent(level=nil)
|
|
36
38
|
level ||= @tracing_level
|
|
37
39
|
' ' * level
|
|
38
40
|
end
|
|
41
|
+
|
|
42
|
+
def higher_tracing_level
|
|
43
|
+
self.tracing_level += 1
|
|
44
|
+
yield
|
|
45
|
+
self.tracing_level -= 1
|
|
46
|
+
end
|
|
39
47
|
end
|
|
40
48
|
|
|
41
49
|
# Trace RASN1 parsing to +io+.
|
|
42
50
|
# All parsing methods called in block are traced to +io+. Each ASN.1 element is
|
|
43
51
|
# traced in a line showing element's id, its length and its data.
|
|
44
|
-
# @param [IO]
|
|
52
|
+
# @param io [IO]
|
|
53
|
+
# @return [void]
|
|
45
54
|
# @example
|
|
46
55
|
# RASN1.trace do
|
|
47
56
|
# RASN1.parse("\x02\x01\x01") # puts "INTEGER id: 2 (0x02), len: 1 (0x01), data: 0x01"
|
|
48
57
|
# end
|
|
49
58
|
# RASN1.parse("\x01\x01\xff") # puts nothing onto STDOUT
|
|
50
|
-
# @return [void]
|
|
51
59
|
def self.trace(io=$stdout)
|
|
52
60
|
@tracer = Tracer.new(io)
|
|
53
61
|
Tracer::TRACED_CLASSES.each(&:start_tracing)
|
|
@@ -62,6 +70,7 @@ module RASN1
|
|
|
62
70
|
end
|
|
63
71
|
|
|
64
72
|
# @private
|
|
73
|
+
# @return [Tracer]
|
|
65
74
|
def self.tracer
|
|
66
75
|
@tracer
|
|
67
76
|
end
|
|
@@ -71,6 +80,7 @@ module RASN1
|
|
|
71
80
|
class << self
|
|
72
81
|
# @private
|
|
73
82
|
# Patch {#do_parse} to add tracing ability
|
|
83
|
+
# @return [void]
|
|
74
84
|
def start_tracing
|
|
75
85
|
alias_method :do_parse_without_tracing, :do_parse
|
|
76
86
|
alias_method :do_parse, :do_parse_with_tracing
|
|
@@ -80,6 +90,7 @@ module RASN1
|
|
|
80
90
|
|
|
81
91
|
# @private
|
|
82
92
|
# Unpatch {#do_parse} to remove tracing ability
|
|
93
|
+
# @return [void]
|
|
83
94
|
def stop_tracing
|
|
84
95
|
alias_method :do_parse, :do_parse_without_tracing
|
|
85
96
|
alias_method :do_parse_explicit, :do_parse_explicit_without_tracing
|
|
@@ -88,6 +99,7 @@ module RASN1
|
|
|
88
99
|
|
|
89
100
|
# @private
|
|
90
101
|
# Parse +der+ with tracing abillity
|
|
102
|
+
# @!macro do_parse
|
|
91
103
|
# @see #parse!
|
|
92
104
|
def do_parse_with_tracing(der, ber:)
|
|
93
105
|
ret = do_parse_without_tracing(der, ber: ber)
|
|
@@ -95,10 +107,13 @@ module RASN1
|
|
|
95
107
|
ret
|
|
96
108
|
end
|
|
97
109
|
|
|
110
|
+
# @private
|
|
111
|
+
# Delegate with tracing to explicit type to generate sub-value
|
|
112
|
+
# @param data [String]
|
|
113
|
+
# @return [void]
|
|
114
|
+
# @see #parse!
|
|
98
115
|
def do_parse_explicit_with_tracing(data)
|
|
99
|
-
RASN1.tracer.
|
|
100
|
-
do_parse_explicit_without_tracing(data)
|
|
101
|
-
RASN1.tracer.tracing_level -= 1
|
|
116
|
+
RASN1.tracer.higher_tracing_level { do_parse_explicit_without_tracing(data) }
|
|
102
117
|
end
|
|
103
118
|
end
|
|
104
119
|
|
|
@@ -106,6 +121,7 @@ module RASN1
|
|
|
106
121
|
class << self
|
|
107
122
|
# @private
|
|
108
123
|
# Patch {#parse!} to add tracing ability
|
|
124
|
+
# @return [void]
|
|
109
125
|
def start_tracing
|
|
110
126
|
alias_method :parse_without_tracing, :parse!
|
|
111
127
|
alias_method :parse!, :parse_with_tracing
|
|
@@ -113,6 +129,7 @@ module RASN1
|
|
|
113
129
|
|
|
114
130
|
# @private
|
|
115
131
|
# Unpatch {#parse!} to remove tracing ability
|
|
132
|
+
# @return [void]
|
|
116
133
|
def stop_tracing
|
|
117
134
|
alias_method :parse!, :parse_without_tracing
|
|
118
135
|
end
|
|
@@ -120,6 +137,7 @@ module RASN1
|
|
|
120
137
|
|
|
121
138
|
# @private
|
|
122
139
|
# Parse +der+ with tracing abillity
|
|
140
|
+
# @!macro do_parse
|
|
123
141
|
# @see #parse!
|
|
124
142
|
def parse_with_tracing(der, ber: false)
|
|
125
143
|
RASN1.tracer.trace(self.trace)
|
|
@@ -131,6 +149,7 @@ module RASN1
|
|
|
131
149
|
class << self
|
|
132
150
|
# @private
|
|
133
151
|
# Patch {#der_to_value} to add tracing ability
|
|
152
|
+
# @return [void]
|
|
134
153
|
def start_tracing
|
|
135
154
|
alias_method :der_to_value_without_tracing, :der_to_value
|
|
136
155
|
alias_method :der_to_value, :der_to_value_with_tracing
|
|
@@ -138,6 +157,7 @@ module RASN1
|
|
|
138
157
|
|
|
139
158
|
# @private
|
|
140
159
|
# Unpatch {#der_to_value} to remove tracing ability
|
|
160
|
+
# @return [void]
|
|
141
161
|
def stop_tracing
|
|
142
162
|
alias_method :der_to_value, :der_to_value_without_tracing
|
|
143
163
|
end
|
|
@@ -145,10 +165,9 @@ module RASN1
|
|
|
145
165
|
|
|
146
166
|
# @private
|
|
147
167
|
# der_to_value +der+ with tracing abillity
|
|
168
|
+
# @!macro do_parse
|
|
148
169
|
def der_to_value_with_tracing(der, ber: false)
|
|
149
|
-
RASN1.tracer.
|
|
150
|
-
der_to_value_without_tracing(der, ber: ber)
|
|
151
|
-
RASN1.tracer.tracing_level -= 1
|
|
170
|
+
RASN1.tracer.higher_tracing_level { der_to_value_without_tracing(der, ber: ber) }
|
|
152
171
|
end
|
|
153
172
|
end
|
|
154
173
|
|
|
@@ -156,6 +175,7 @@ module RASN1
|
|
|
156
175
|
class << self
|
|
157
176
|
# @private
|
|
158
177
|
# Patch {#der_to_value} to add tracing ability
|
|
178
|
+
# @return [void]
|
|
159
179
|
def start_tracing
|
|
160
180
|
alias_method :der_to_value_without_tracing, :der_to_value
|
|
161
181
|
alias_method :der_to_value, :der_to_value_with_tracing
|
|
@@ -163,6 +183,7 @@ module RASN1
|
|
|
163
183
|
|
|
164
184
|
# @private
|
|
165
185
|
# Unpatch {#der_to_value} to remove tracing ability
|
|
186
|
+
# @return [void]
|
|
166
187
|
def stop_tracing
|
|
167
188
|
alias_method :der_to_value, :der_to_value_without_tracing
|
|
168
189
|
end
|
|
@@ -170,10 +191,9 @@ module RASN1
|
|
|
170
191
|
|
|
171
192
|
# @private
|
|
172
193
|
# der_to_value +der+ with tracing abillity
|
|
194
|
+
# @!macro do_parse
|
|
173
195
|
def der_to_value_with_tracing(der, ber: false)
|
|
174
|
-
RASN1.tracer.
|
|
175
|
-
der_to_value_without_tracing(der, ber: ber)
|
|
176
|
-
RASN1.tracer.tracing_level -= 1
|
|
196
|
+
RASN1.tracer.higher_tracing_level { der_to_value_without_tracing(der, ber: ber) }
|
|
177
197
|
end
|
|
178
198
|
end
|
|
179
199
|
end
|
data/lib/rasn1/types/any.rb
CHANGED
|
@@ -10,7 +10,24 @@ module RASN1
|
|
|
10
10
|
module Types
|
|
11
11
|
# ASN.1 ANY: accepts any types
|
|
12
12
|
#
|
|
13
|
+
# ANY is often used with an {ObjectId} to detect real type.
|
|
14
|
+
#
|
|
15
|
+
# On encoding, ANY is replaced by its values (which must be an RASN1 type).
|
|
13
16
|
# If `any#value` is `nil` and Any object is not {#optional?}, `any` will be encoded as a {Null} object.
|
|
17
|
+
#
|
|
18
|
+
# @example Parsing with any model
|
|
19
|
+
# class AnyModel < RASN1::Model
|
|
20
|
+
# sequence :seq,
|
|
21
|
+
# content: [objectid(:id), any(:data)]
|
|
22
|
+
# end
|
|
23
|
+
# model = AnyModel.new
|
|
24
|
+
# model.parse!("\x30\x09\x06\x03\x2a\x03\x04\x02\x02\x01\xff")
|
|
25
|
+
# model[:id].value #=> "1.2.3.4"
|
|
26
|
+
# model[:data].value #=> "\x02\x02\x01\xff"
|
|
27
|
+
# # As we knwon object with id 1.2.3.4 is an integer, with then parse data as such
|
|
28
|
+
# data = RASN1::Types::Integer.new
|
|
29
|
+
# data.parse!(model[:data].value)
|
|
30
|
+
# data.value #=> 511
|
|
14
31
|
# @author Sylvain Daubert
|
|
15
32
|
class Any < Base
|
|
16
33
|
# @return [String] DER-formated string
|
|
@@ -27,21 +44,22 @@ module RASN1
|
|
|
27
44
|
end
|
|
28
45
|
end
|
|
29
46
|
|
|
47
|
+
# @return [Boolean]
|
|
30
48
|
def can_build?
|
|
31
49
|
value? || !optional?
|
|
32
50
|
end
|
|
33
51
|
|
|
34
52
|
# Parse a DER string. This method updates object: {#value} will be a DER
|
|
35
53
|
# string.
|
|
36
|
-
# @param [String]
|
|
37
|
-
# @param [Boolean]
|
|
54
|
+
# @param der [String] DER string
|
|
55
|
+
# @param ber [Boolean] if +true+, accept BER encoding
|
|
38
56
|
# @return [Integer] total number of parsed bytes
|
|
39
57
|
def parse!(der, ber: false)
|
|
40
58
|
total_length, _data = do_parse(der, ber: ber)
|
|
41
59
|
total_length
|
|
42
60
|
end
|
|
43
61
|
|
|
44
|
-
# @param [::Integer]
|
|
62
|
+
# @param level [::Integer]
|
|
45
63
|
# @return [String]
|
|
46
64
|
def inspect(level=0)
|
|
47
65
|
str = common_inspect(level)
|
|
@@ -66,6 +84,7 @@ module RASN1
|
|
|
66
84
|
|
|
67
85
|
private
|
|
68
86
|
|
|
87
|
+
# @param level [Integer]
|
|
69
88
|
def common_inspect(level)
|
|
70
89
|
lvl = [0, level].max
|
|
71
90
|
str = ' ' * lvl
|
|
@@ -77,6 +96,7 @@ module RASN1
|
|
|
77
96
|
end
|
|
78
97
|
|
|
79
98
|
# @private
|
|
99
|
+
# @!macro do_parse
|
|
80
100
|
# @see Types::Base#do_parse
|
|
81
101
|
def do_parse(der, ber: false)
|
|
82
102
|
if der.empty?
|
|
@@ -96,6 +116,7 @@ module RASN1
|
|
|
96
116
|
[total_length, real_value]
|
|
97
117
|
end
|
|
98
118
|
|
|
119
|
+
# @return [String]
|
|
99
120
|
def trace_any
|
|
100
121
|
msg_type(no_id: true) << trace_data(value)
|
|
101
122
|
end
|