rasn1 0.14.0 → 0.16.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 +13 -6
- data/lib/rasn1/model.rb +186 -146
- data/lib/rasn1/tracer.rb +4 -4
- data/lib/rasn1/types/any.rb +5 -3
- data/lib/rasn1/types/base.rb +49 -32
- data/lib/rasn1/types/bit_string.rb +12 -7
- data/lib/rasn1/types/bmp_string.rb +3 -11
- data/lib/rasn1/types/boolean.rb +16 -9
- data/lib/rasn1/types/choice.rb +43 -3
- data/lib/rasn1/types/constrained.rb +5 -2
- data/lib/rasn1/types/generalized_time.rb +32 -24
- data/lib/rasn1/types/ia5string.rb +3 -11
- data/lib/rasn1/types/integer.rb +13 -9
- data/lib/rasn1/types/null.rb +11 -6
- data/lib/rasn1/types/numeric_string.rb +13 -6
- data/lib/rasn1/types/object_id.rb +33 -21
- data/lib/rasn1/types/octet_string.rb +26 -0
- data/lib/rasn1/types/printable_string.rb +13 -6
- data/lib/rasn1/types/sequence.rb +16 -12
- data/lib/rasn1/types/sequence_of.rb +15 -11
- data/lib/rasn1/types/universal_string.rb +3 -11
- data/lib/rasn1/types/utc_time.rb +17 -7
- data/lib/rasn1/types/utf8_string.rb +3 -11
- data/lib/rasn1/types/visible_string.rb +14 -2
- data/lib/rasn1/types.rb +6 -5
- data/lib/rasn1/version.rb +2 -1
- data/lib/rasn1/wrapper.rb +72 -18
- data/lib/rasn1.rb +5 -2
- metadata +2 -2
@@ -7,6 +7,8 @@ module RASN1
|
|
7
7
|
class PrintableString < OctetString
|
8
8
|
# PrintableString id value
|
9
9
|
ID = 19
|
10
|
+
# Invalid characters in PrintableString
|
11
|
+
INVALID_CHARS = %r{([^a-zA-Z0-9 '=()+,\-./:?])}
|
10
12
|
|
11
13
|
# Get ASN.1 type
|
12
14
|
# @return [String]
|
@@ -14,6 +16,16 @@ module RASN1
|
|
14
16
|
'PrintableString'
|
15
17
|
end
|
16
18
|
|
19
|
+
# Make string value from +der+ string
|
20
|
+
# @param [String] der
|
21
|
+
# @param [::Boolean] ber
|
22
|
+
# @return [void]
|
23
|
+
# @raise [ASN1Error] invalid characters detected
|
24
|
+
def der_to_value(der, ber: false)
|
25
|
+
super
|
26
|
+
check_characters
|
27
|
+
end
|
28
|
+
|
17
29
|
private
|
18
30
|
|
19
31
|
def value_to_der
|
@@ -21,13 +33,8 @@ module RASN1
|
|
21
33
|
@value.to_s.b
|
22
34
|
end
|
23
35
|
|
24
|
-
def der_to_value(der, ber: false)
|
25
|
-
super
|
26
|
-
check_characters
|
27
|
-
end
|
28
|
-
|
29
36
|
def check_characters
|
30
|
-
m = @value.to_s.match(
|
37
|
+
m = @value.to_s.match(INVALID_CHARS)
|
31
38
|
raise ASN1Error, "PRINTABLE STRING #{@name}: invalid character: '#{m[1]}'" if m
|
32
39
|
end
|
33
40
|
end
|
data/lib/rasn1/types/sequence.rb
CHANGED
@@ -66,22 +66,15 @@ module RASN1
|
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
when Array
|
74
|
-
@value.map(&:to_der).join
|
75
|
-
else
|
76
|
-
@value.to_s
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
69
|
+
# Make sequence value from +der+ string
|
70
|
+
# @param [String] der
|
71
|
+
# @param [::Boolean] ber
|
72
|
+
# @return [void]
|
80
73
|
def der_to_value(der, ber: false) # rubocop:disable Lint/UnusedMethodArgument
|
81
74
|
if @value.is_a?(Array) && !@value.empty?
|
82
75
|
nb_bytes = 0
|
83
76
|
@value.each do |element|
|
84
|
-
nb_bytes += element.parse!(der[nb_bytes
|
77
|
+
nb_bytes += element.parse!(der[nb_bytes..])
|
85
78
|
end
|
86
79
|
else
|
87
80
|
@value = der
|
@@ -89,6 +82,17 @@ module RASN1
|
|
89
82
|
end
|
90
83
|
end
|
91
84
|
|
85
|
+
private
|
86
|
+
|
87
|
+
def value_to_der
|
88
|
+
case @value
|
89
|
+
when Array
|
90
|
+
@value.map(&:to_der).join
|
91
|
+
else
|
92
|
+
@value.to_s
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
92
96
|
def trace_data
|
93
97
|
''
|
94
98
|
end
|
@@ -125,6 +125,21 @@ module RASN1
|
|
125
125
|
str
|
126
126
|
end
|
127
127
|
|
128
|
+
# Make sequence of value from +der+ string
|
129
|
+
# @param [String] der
|
130
|
+
# @param [::Boolean] ber
|
131
|
+
# @return [void]
|
132
|
+
def der_to_value(der, ber: false) # rubocop:disable Lint/UnusedMethodArgument
|
133
|
+
@value = []
|
134
|
+
nb_bytes = 0
|
135
|
+
|
136
|
+
while nb_bytes < der.length
|
137
|
+
type = of_type_class.new
|
138
|
+
nb_bytes += type.parse!(der[nb_bytes, der.length])
|
139
|
+
@value << type
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
128
143
|
private
|
129
144
|
|
130
145
|
def of_type_class
|
@@ -139,17 +154,6 @@ module RASN1
|
|
139
154
|
@value.map(&:to_der).join
|
140
155
|
end
|
141
156
|
|
142
|
-
def der_to_value(der, ber: false) # rubocop:disable Lint/UnusedMethodArgument
|
143
|
-
@value = []
|
144
|
-
nb_bytes = 0
|
145
|
-
|
146
|
-
while nb_bytes < der.length
|
147
|
-
type = of_type_class.new
|
148
|
-
nb_bytes += type.parse!(der[nb_bytes, der.length])
|
149
|
-
@value << type
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
157
|
def explicit_type
|
154
158
|
self.class.new(self.of_type, name: name)
|
155
159
|
end
|
@@ -8,23 +8,15 @@ module RASN1
|
|
8
8
|
class UniversalString < OctetString
|
9
9
|
# UniversalString id value
|
10
10
|
ID = 28
|
11
|
+
# UniversalString encoding
|
12
|
+
# @since 0.15.0
|
13
|
+
ENCODING = Encoding::UTF_32BE
|
11
14
|
|
12
15
|
# Get ASN.1 type
|
13
16
|
# @return [String]
|
14
17
|
def self.type
|
15
18
|
'UniversalString'
|
16
19
|
end
|
17
|
-
|
18
|
-
private
|
19
|
-
|
20
|
-
def value_to_der
|
21
|
-
@value.to_s.dup.encode('UTF-32BE').b
|
22
|
-
end
|
23
|
-
|
24
|
-
def der_to_value(der, ber: false)
|
25
|
-
super
|
26
|
-
@value = der.to_s.dup.force_encoding('UTF-32BE')
|
27
|
-
end
|
28
20
|
end
|
29
21
|
end
|
30
22
|
end
|
data/lib/rasn1/types/utc_time.rb
CHANGED
@@ -27,12 +27,11 @@ module RASN1
|
|
27
27
|
'UTCTime'
|
28
28
|
end
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
30
|
+
# Make time value from +der+ string
|
31
|
+
# @param [String] der
|
32
|
+
# @param [::Boolean] ber
|
33
|
+
# @return [void]
|
34
|
+
# @raise [ASN1Error] unrecognized time format
|
36
35
|
def der_to_value(der, ber: false) # rubocop:disable Lint/UnusedMethodArgument
|
37
36
|
format = case der.size
|
38
37
|
when 11, 15
|
@@ -44,7 +43,18 @@ module RASN1
|
|
44
43
|
raise ASN1Error, "#{prefix}: unrecognized format: #{der}"
|
45
44
|
end
|
46
45
|
century = (Time.now.year / 100).to_s
|
47
|
-
|
46
|
+
begin
|
47
|
+
@value = Strptime.new(format).exec(century + der)
|
48
|
+
rescue ArgumentError
|
49
|
+
prefix = @name.nil? ? type : "tag #{@name}"
|
50
|
+
raise ASN1Error, "#{prefix}: unrecognized format: #{der}"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def value_to_der
|
57
|
+
@value.getutc.strftime('%y%m%d%H%M%SZ')
|
48
58
|
end
|
49
59
|
|
50
60
|
def trace_data
|
@@ -7,23 +7,15 @@ module RASN1
|
|
7
7
|
class Utf8String < OctetString
|
8
8
|
# Utf8String id value
|
9
9
|
ID = 12
|
10
|
+
# Utf8String encoding
|
11
|
+
# @since 0.15.0
|
12
|
+
ENCODING = Encoding::UTF_8
|
10
13
|
|
11
14
|
# Get ASN.1 type
|
12
15
|
# @return [String]
|
13
16
|
def self.type
|
14
17
|
'UTF8String'
|
15
18
|
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def value_to_der
|
20
|
-
@value.to_s.dup.force_encoding('UTF-8').b
|
21
|
-
end
|
22
|
-
|
23
|
-
def der_to_value(der, ber: false)
|
24
|
-
super
|
25
|
-
@value = der.dup.force_encoding('UTF-8')
|
26
|
-
end
|
27
19
|
end
|
28
20
|
end
|
29
21
|
end
|
@@ -2,14 +2,26 @@
|
|
2
2
|
|
3
3
|
module RASN1
|
4
4
|
module Types
|
5
|
+
# Create VisibleString as a Constrained subclass of IA5String
|
6
|
+
Types.define_type(:VisibleString, from: IA5String) do |value|
|
7
|
+
value.nil? || value.chars.all? { |c| c.ord.between?(32, 126) }
|
8
|
+
end
|
9
|
+
|
5
10
|
# ASN.1 Visible String
|
6
|
-
#
|
7
|
-
|
11
|
+
#
|
12
|
+
# VisibleString may only contain ASCII characters from range 32 to 126.
|
13
|
+
# @author LemonTree55
|
14
|
+
# @since 0.3.0
|
15
|
+
# @since 0.15.0 VisibleString is defined as a constrained {IA5String}. It will now raise if value contains a non-visible character.
|
16
|
+
class VisibleString
|
8
17
|
# VisibleString id value
|
18
|
+
# @since 0.3.0
|
9
19
|
ID = 26
|
10
20
|
|
11
21
|
# Get ASN.1 type
|
12
22
|
# @return [String]
|
23
|
+
# @author Sylvain Daubert
|
24
|
+
# @since 0.3.0
|
13
25
|
def self.type
|
14
26
|
'VisibleString'
|
15
27
|
end
|
data/lib/rasn1/types.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'types/constrained'
|
4
|
+
|
3
5
|
module RASN1
|
4
6
|
# This modules is a namesapce for all ASN.1 type classes.
|
5
7
|
# @author Sylvain Daubert
|
@@ -33,17 +35,17 @@ module RASN1
|
|
33
35
|
def self.decode_identifier_octets(der)
|
34
36
|
first_octet = der.unpack1('C').to_i
|
35
37
|
asn1_class = Types::Base::CLASSES.key(first_octet & Types::Base::CLASS_MASK) || :universal
|
36
|
-
pc = (
|
38
|
+
pc = first_octet.anybits?(Types::Constructed::ASN1_PC) ? :constructed : :primitive
|
37
39
|
id = first_octet & Types::Base::MULTI_OCTETS_ID
|
38
40
|
|
39
41
|
size = if id == Types::Base::MULTI_OCTETS_ID
|
40
42
|
id = 0
|
41
43
|
count = 1
|
42
|
-
der[1
|
44
|
+
der[1..].to_s.bytes.each do |octet|
|
43
45
|
count += 1
|
44
46
|
|
45
47
|
id = (id << 7) | (octet & 0x7f)
|
46
|
-
break if (
|
48
|
+
break if octet.nobits?(0x80)
|
47
49
|
end
|
48
50
|
count
|
49
51
|
else
|
@@ -85,7 +87,7 @@ module RASN1
|
|
85
87
|
|
86
88
|
# Define a new ASN.1 type from a base one.
|
87
89
|
# This new type may have a constraint defines on it.
|
88
|
-
# @param [Symbol,String] name
|
90
|
+
# @param [Symbol,String] name new type name. Must start with a capital letter.
|
89
91
|
# @param [Types::Base] from class from which inherits
|
90
92
|
# @param [Module] in_module module in which creates new type (default to {RASN1::Types})
|
91
93
|
# @return [Class] newly created class
|
@@ -135,7 +137,6 @@ require_relative 'types/utf8_string'
|
|
135
137
|
require_relative 'types/numeric_string'
|
136
138
|
require_relative 'types/printable_string'
|
137
139
|
require_relative 'types/ia5string'
|
138
|
-
require_relative 'types/visible_string'
|
139
140
|
require_relative 'types/constructed'
|
140
141
|
require_relative 'types/sequence'
|
141
142
|
require_relative 'types/sequence_of'
|
data/lib/rasn1/version.rb
CHANGED
data/lib/rasn1/wrapper.rb
CHANGED
@@ -6,12 +6,13 @@ module RASN1
|
|
6
6
|
# This class is used to wrap a {Types::Base} or {Model} instance to force its options.
|
7
7
|
#
|
8
8
|
# == Usage
|
9
|
-
# This class may be used to wrap another RASN1 object by
|
9
|
+
# This class may be used to wrap another RASN1 object by 4 ways:
|
10
10
|
# * wrap an object to modify its options,
|
11
11
|
# * implicitly wrap an object (i.e. change its tag),
|
12
|
-
# * explicitly wrap an object (i.e wrap the object in another explicit ASN.1 tag)
|
12
|
+
# * explicitly wrap an object (i.e wrap the object in another explicit ASN.1 tag),
|
13
|
+
# * wrap a choice model to reuse it in its own definition.
|
13
14
|
#
|
14
|
-
# @example
|
15
|
+
# @example Wrapping object
|
15
16
|
# # object to wrap
|
16
17
|
# int = RASN1::Types::Integer.new(implicit: 1) # its tag is 0x81
|
17
18
|
# # simple wrapper, change an option
|
@@ -20,7 +21,18 @@ module RASN1
|
|
20
21
|
# wrapper = RASN1::Wrapper.new(int, implicit: 3) # wrapped int tag is now 0x83
|
21
22
|
# # explicit wrapper
|
22
23
|
# wrapper = RASN1::Wrapper.new(int, explicit: 4) # int tag is always 0x81, but it is wrapped in a 0x84 tag
|
24
|
+
# @example Wrapping a choice to make it recursive
|
25
|
+
# class RecursiveChoice < RASN1::Model
|
26
|
+
# choice :choice,
|
27
|
+
# content: [
|
28
|
+
# integer(:value, implicit: 1),
|
29
|
+
# wrapper(model(:recursive, RecursiveChoice), implicit:2)
|
30
|
+
# ]
|
31
|
+
# end
|
23
32
|
# @since 0.12.0
|
33
|
+
# @since 0.15.0 Wrappers are lazy. They allocate their inner element only when needed (i.e. when calling {#to_der}, {#parse!} or {#element})
|
34
|
+
# @author Sylvain Daubert
|
35
|
+
# @author LemonTree55
|
24
36
|
class Wrapper < SimpleDelegator
|
25
37
|
# @private Private class used to build/parse explicit wrappers
|
26
38
|
class ExplicitWrapper < Types::Base
|
@@ -54,15 +66,16 @@ module RASN1
|
|
54
66
|
# @param [Types::Base,Model] element element to wrap
|
55
67
|
# @param [Hash] options
|
56
68
|
def initialize(element, options={})
|
69
|
+
@lazy = true
|
57
70
|
opts = explicit_implicit(options)
|
58
71
|
|
59
72
|
if explicit?
|
60
73
|
generate_explicit_wrapper(opts)
|
61
|
-
|
74
|
+
@element_options_to_merge = generate_explicit_wrapper_options(opts)
|
62
75
|
@options = opts
|
63
76
|
else
|
64
|
-
opts[:value] = element.value
|
65
|
-
|
77
|
+
opts[:value] = element.value if element.respond_to?(:value)
|
78
|
+
@element_options_to_merge = opts
|
66
79
|
@options = {}
|
67
80
|
end
|
68
81
|
raise RASN1::Error, 'Cannot be implicit and explicit' if explicit? && implicit?
|
@@ -84,7 +97,10 @@ module RASN1
|
|
84
97
|
|
85
98
|
# Convert wrapper and its element to a DER string
|
86
99
|
# @return [String]
|
100
|
+
# @since 0.12.0
|
101
|
+
# @since 0.15.0 Allocate element (lazy wrapper)
|
87
102
|
def to_der
|
103
|
+
lazy_generation
|
88
104
|
if implicit?
|
89
105
|
el = generate_implicit_element
|
90
106
|
el.to_der
|
@@ -101,7 +117,10 @@ module RASN1
|
|
101
117
|
# @param [Boolean] ber if +true+, accept BER encoding
|
102
118
|
# @return [Integer] total number of parsed bytes
|
103
119
|
# @raise [ASN1Error] error on parsing
|
120
|
+
# @since 0.12.0
|
121
|
+
# @since 0.15.0 Allocate element (lazy wrapper)
|
104
122
|
def parse!(der, ber: false)
|
123
|
+
lazy_generation
|
105
124
|
if implicit?
|
106
125
|
el = generate_implicit_element
|
107
126
|
parsed = el.parse!(der, ber: ber)
|
@@ -116,11 +135,25 @@ module RASN1
|
|
116
135
|
end
|
117
136
|
end
|
118
137
|
|
138
|
+
# @private
|
139
|
+
# @see Types::Base#do_parse
|
140
|
+
def do_parse(der, ber: false)
|
141
|
+
if implicit?
|
142
|
+
generate_implicit_element(Types::Base.new(constructed: element.constructed?)).do_parse(der, ber: ber)
|
143
|
+
elsif explicit?
|
144
|
+
@explicit_wrapper.do_parse(der, ber: ber)
|
145
|
+
else
|
146
|
+
element.do_parse(der, ber: ber)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
119
150
|
# @return [Boolean]
|
120
151
|
# @see Types::Base#value?
|
121
152
|
def value?
|
122
153
|
if explicit?
|
123
154
|
@explicit_wrapper.value?
|
155
|
+
elsif __getobj__.is_a?(Class)
|
156
|
+
false
|
124
157
|
else
|
125
158
|
__getobj__.value?
|
126
159
|
end
|
@@ -128,8 +161,10 @@ module RASN1
|
|
128
161
|
|
129
162
|
# Return Wrapped element
|
130
163
|
# @return [Types::Base,Model]
|
164
|
+
# @since 0.12.0
|
165
|
+
# @since 0.15.0 Allocate element (lazy wrapper)
|
131
166
|
def element
|
132
|
-
|
167
|
+
lazy_generation
|
133
168
|
end
|
134
169
|
|
135
170
|
# @return [::Integer]
|
@@ -140,14 +175,14 @@ module RASN1
|
|
140
175
|
elsif explicit?
|
141
176
|
@explicit
|
142
177
|
else
|
143
|
-
|
178
|
+
lazy_generation(register: false).id
|
144
179
|
end
|
145
180
|
end
|
146
181
|
|
147
182
|
# @return [Symbol]
|
148
183
|
# @see Types::Base#asn1_class
|
149
184
|
def asn1_class
|
150
|
-
return
|
185
|
+
return lazy_generation(register: false).asn1_class unless @options.key?(:class)
|
151
186
|
|
152
187
|
@options[:class]
|
153
188
|
end
|
@@ -155,7 +190,7 @@ module RASN1
|
|
155
190
|
# @return [Boolean]
|
156
191
|
# @see Types::Base#constructed
|
157
192
|
def constructed?
|
158
|
-
return
|
193
|
+
return lazy_generation(register: false).constructed? unless @options.key?(:constructed)
|
159
194
|
|
160
195
|
@options[:constructed]
|
161
196
|
end
|
@@ -169,9 +204,9 @@ module RASN1
|
|
169
204
|
# @param [::Integer] level
|
170
205
|
# @return [String]
|
171
206
|
def inspect(level=0)
|
172
|
-
return super(
|
207
|
+
return super() unless explicit?
|
173
208
|
|
174
|
-
@explicit_wrapper.inspect(level) << ' ' << super(
|
209
|
+
@explicit_wrapper.inspect(level) << ' ' << super()
|
175
210
|
end
|
176
211
|
|
177
212
|
private
|
@@ -196,14 +231,33 @@ module RASN1
|
|
196
231
|
new_opts
|
197
232
|
end
|
198
233
|
|
199
|
-
def generate_implicit_element
|
200
|
-
el = element.dup
|
201
|
-
if
|
202
|
-
|
234
|
+
def generate_implicit_element(from=nil)
|
235
|
+
el = (from || element).dup
|
236
|
+
el.options = if element.explicit?
|
237
|
+
el.options.merge(explicit: @implicit)
|
238
|
+
else
|
239
|
+
el.options.merge(implicit: @implicit)
|
240
|
+
end
|
241
|
+
el
|
242
|
+
end
|
243
|
+
|
244
|
+
def lazy_generation(register: true)
|
245
|
+
return __getobj__ unless @lazy
|
246
|
+
|
247
|
+
real_element = __getobj__
|
248
|
+
case real_element
|
249
|
+
when Types::Base, Model
|
250
|
+
real_element.options = real_element.options.merge(@element_options_to_merge)
|
251
|
+
@lazy = false
|
252
|
+
real_element
|
203
253
|
else
|
204
|
-
el
|
254
|
+
el = real_element.new(@element_options_to_merge)
|
255
|
+
if register
|
256
|
+
@lazy = false
|
257
|
+
__setobj__(el)
|
258
|
+
end
|
259
|
+
el
|
205
260
|
end
|
206
|
-
el
|
207
261
|
end
|
208
262
|
end
|
209
263
|
end
|
data/lib/rasn1.rb
CHANGED
@@ -7,6 +7,9 @@ require_relative 'rasn1/model'
|
|
7
7
|
require_relative 'rasn1/wrapper'
|
8
8
|
require_relative 'rasn1/tracer'
|
9
9
|
|
10
|
+
# Constrained types
|
11
|
+
require_relative 'rasn1/types/visible_string'
|
12
|
+
|
10
13
|
# Rasn1 is a pure ruby library to parse, decode and encode ASN.1 data.
|
11
14
|
# @author Sylvain Daubert
|
12
15
|
module RASN1
|
@@ -23,7 +26,7 @@ module RASN1
|
|
23
26
|
# @param [String] der binary string to parse
|
24
27
|
# @param [Boolean] ber if +true+, decode a BER string, else a DER one
|
25
28
|
# @return [Types::Base]
|
26
|
-
def self.parse(der, ber: false) # rubocop:disable Metrics
|
29
|
+
def self.parse(der, ber: false) # rubocop:disable Metrics/AbcSize
|
27
30
|
type = Types.id2type(der)
|
28
31
|
type.parse!(der, ber: ber)
|
29
32
|
|
@@ -33,7 +36,7 @@ module RASN1
|
|
33
36
|
RASN1.tracer.tracing_level += 1 unless RASN1.tracer.nil?
|
34
37
|
until subder.empty?
|
35
38
|
ary << self.parse(subder)
|
36
|
-
subder = subder[ary.last.to_der.size
|
39
|
+
subder = subder[ary.last.to_der.size..]
|
37
40
|
end
|
38
41
|
RASN1.tracer.tracing_level -= 1 unless RASN1.tracer.nil?
|
39
42
|
type.value = ary
|
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.16.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- LemonTree55
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-06-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: strptime
|