rasn2 0.16.0 → 1.0.1
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 → rasn2}/errors.rb +2 -2
- data/lib/rasn2/helpers/colorize.rb +119 -0
- data/lib/{rasn1 → rasn2}/model.rb +16 -12
- data/lib/{rasn1 → rasn2}/schema_parser.rb +10 -10
- data/lib/{rasn1 → rasn2}/tracer.rb +15 -14
- data/lib/{rasn1 → rasn2}/types/any.rb +18 -34
- data/lib/{rasn1 → rasn2}/types/base.rb +120 -82
- data/lib/{rasn1 → rasn2}/types/bit_string.rb +3 -6
- data/lib/{rasn1 → rasn2}/types/bmp_string.rb +1 -1
- data/lib/{rasn1 → rasn2}/types/boolean.rb +2 -2
- data/lib/{rasn1 → rasn2}/types/choice.rb +5 -5
- data/lib/{rasn1 → rasn2}/types/constrained.rb +2 -2
- data/lib/{rasn1 → rasn2}/types/constructed.rb +1 -24
- data/lib/{rasn1 → rasn2}/types/enumerated.rb +3 -3
- data/lib/{rasn1 → rasn2}/types/generalized_time.rb +1 -1
- data/lib/{rasn1 → rasn2}/types/ia5_string.rb +5 -1
- data/lib/{rasn1 → rasn2}/types/integer.rb +3 -2
- data/lib/{rasn1 → rasn2}/types/null.rb +6 -5
- data/lib/{rasn1 → rasn2}/types/numeric_string.rb +1 -1
- data/lib/{rasn1 → rasn2}/types/object_id.rb +1 -1
- data/lib/{rasn1 → rasn2}/types/octet_string.rb +3 -6
- data/lib/{rasn1 → rasn2}/types/primitive.rb +1 -1
- data/lib/{rasn1 → rasn2}/types/printable_string.rb +1 -1
- data/lib/{rasn1 → rasn2}/types/sequence.rb +6 -6
- data/lib/{rasn1 → rasn2}/types/sequence_of.rb +20 -25
- data/lib/{rasn1 → rasn2}/types/set.rb +5 -5
- data/lib/{rasn1 → rasn2}/types/set_of.rb +1 -1
- data/lib/{rasn1 → rasn2}/types/tag.rb +13 -28
- data/lib/{rasn1 → rasn2}/types/universal_string.rb +1 -1
- data/lib/{rasn1 → rasn2}/types/utc_time.rb +1 -1
- data/lib/{rasn1 → rasn2}/types/utf8_string.rb +1 -1
- data/lib/{rasn1 → rasn2}/types/visible_string.rb +1 -1
- data/lib/{rasn1 → rasn2}/types.rb +7 -5
- data/lib/{rasn1 → rasn2}/value_notation.rb +5 -5
- data/lib/rasn2/version.rb +6 -0
- data/lib/{rasn1 → rasn2}/wrapper.rb +8 -15
- data/lib/{rasn1.rb → rasn2.rb} +14 -14
- metadata +40 -40
- data/lib/rasn1/helpers/colorize.rb +0 -76
- data/lib/rasn1/version.rb +0 -6
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
module
|
|
3
|
+
module RASN2
|
|
4
4
|
module Types
|
|
5
5
|
# @abstract This is base class for all ASN.1 types.
|
|
6
6
|
#
|
|
@@ -34,17 +34,21 @@ module RASN1
|
|
|
34
34
|
# -- private tag
|
|
35
35
|
# PType ::= [PRIVATE 2] EXPLICIT INTEGER
|
|
36
36
|
# These types may be defined as:
|
|
37
|
-
# ctype =
|
|
38
|
-
# atype =
|
|
39
|
-
# ptype =
|
|
37
|
+
# ctype = RASN2::Types::Integer.new(explicit: 0) # with explicit, default #asn1_class is :context
|
|
38
|
+
# atype = RASN2::Types::Integer.new(explicit: 1, class: :application)
|
|
39
|
+
# ptype = RASN2::Types::Integer.new(explicit: 2, class: :private)
|
|
40
40
|
# Sometimes, an EXPLICIT type should be CONSTRUCTED. To do that, use +:constructed+
|
|
41
41
|
# option:
|
|
42
|
-
# ptype =
|
|
42
|
+
# ptype = RASN2::Types::Integer.new(explicit: 2, class: :private, constructed: true)
|
|
43
43
|
#
|
|
44
44
|
# Implicit tagged values may also be defined:
|
|
45
|
-
# ctype_implicit =
|
|
45
|
+
# ctype_implicit = RASN2::Types::Integer.new(implicit: 0)
|
|
46
46
|
# @author Sylvain Daubert
|
|
47
47
|
class Base # rubocop:disable Metrics/ClassLength
|
|
48
|
+
ID = nil
|
|
49
|
+
|
|
50
|
+
attr_accessor :model
|
|
51
|
+
|
|
48
52
|
# Allowed ASN.1 classes
|
|
49
53
|
CLASSES = {
|
|
50
54
|
universal: 0x00,
|
|
@@ -54,10 +58,10 @@ module RASN1
|
|
|
54
58
|
}.freeze
|
|
55
59
|
|
|
56
60
|
def colorize(msg)
|
|
57
|
-
tracer ? tracer.colorize(msg) :
|
|
61
|
+
tracer ? tracer.colorize(msg) : self.colorizer.wrap(msg)
|
|
58
62
|
end
|
|
59
63
|
|
|
60
|
-
include
|
|
64
|
+
include RASN2::Helpers::Colorize
|
|
61
65
|
|
|
62
66
|
# Binary mask to get class
|
|
63
67
|
# @private
|
|
@@ -85,7 +89,7 @@ module RASN1
|
|
|
85
89
|
private :raw_data, :raw_length
|
|
86
90
|
|
|
87
91
|
def tracer
|
|
88
|
-
::
|
|
92
|
+
::RASN2.tracer
|
|
89
93
|
end
|
|
90
94
|
|
|
91
95
|
# Get ASN.1 type
|
|
@@ -199,6 +203,10 @@ module RASN1
|
|
|
199
203
|
defined?(@tag) ? @tag == :implicit : nil # rubocop:disable Style/ReturnNilInPredicateMethodDefinition
|
|
200
204
|
end
|
|
201
205
|
|
|
206
|
+
def private?
|
|
207
|
+
self.instance_of?(Types::Tag)
|
|
208
|
+
end
|
|
209
|
+
|
|
202
210
|
# @abstract This method SHOULD be partly implemented by subclasses, which
|
|
203
211
|
# SHOULD respond to +#value_to_der+.
|
|
204
212
|
# @return [String] DER-formated string
|
|
@@ -254,14 +262,43 @@ module RASN1
|
|
|
254
262
|
value_to_der.size
|
|
255
263
|
end
|
|
256
264
|
|
|
265
|
+
def attributes
|
|
266
|
+
attributes = []
|
|
267
|
+
attributes << 'OPTIONAL' if optional?
|
|
268
|
+
attributes << 'CONSTRUCTED' if constructed? && !(self.class < Constructed)
|
|
269
|
+
attributes << 'EXPLICIT' if explicit?
|
|
270
|
+
attributes << 'IMPLICIT' if implicit?
|
|
271
|
+
attributes
|
|
272
|
+
end
|
|
273
|
+
|
|
257
274
|
# @param [Integer] level
|
|
258
275
|
# @return [String]
|
|
259
|
-
def inspect(level=0, color:
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
276
|
+
def inspect(level=0, color: false)
|
|
277
|
+
parts = []
|
|
278
|
+
new_level = level.abs + 1
|
|
279
|
+
|
|
280
|
+
begin_colorizer(color)
|
|
281
|
+
parts << common_inspect(level, color: color)
|
|
282
|
+
|
|
283
|
+
if constructed?
|
|
284
|
+
if @value.is_a?(Array)
|
|
285
|
+
@value.each do |value|
|
|
286
|
+
parts << "\n"
|
|
287
|
+
parts << value.inspect(new_level, color: color).to_s
|
|
288
|
+
end
|
|
289
|
+
else
|
|
290
|
+
parts << "\n"
|
|
291
|
+
if @value.is_a?(Base)
|
|
292
|
+
parts << @value.inspect(new_level, color: color).to_s
|
|
293
|
+
else
|
|
294
|
+
@value.inspect.to_s
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
else
|
|
298
|
+
parts << inspect_value unless inspect_value.empty?
|
|
299
|
+
end
|
|
300
|
+
end_colorizer
|
|
301
|
+
parts.reject(&:empty?).join(' ')
|
|
265
302
|
end
|
|
266
303
|
|
|
267
304
|
# Objects are equal if they have same class AND same DER
|
|
@@ -303,12 +340,14 @@ module RASN1
|
|
|
303
340
|
def trace
|
|
304
341
|
return trace_real if value?
|
|
305
342
|
|
|
306
|
-
|
|
307
|
-
if default.nil?
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
343
|
+
parts = [msg_type]
|
|
344
|
+
parts << if default.nil?
|
|
345
|
+
colorize_nil
|
|
346
|
+
else
|
|
347
|
+
colorize_default(value)
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
parts.reject(&:empty?).join(' ')
|
|
312
351
|
end
|
|
313
352
|
|
|
314
353
|
# @private Parse tage and length from binary string. Return data length and binary data.
|
|
@@ -346,42 +385,28 @@ module RASN1
|
|
|
346
385
|
@value = der
|
|
347
386
|
end
|
|
348
387
|
|
|
349
|
-
private
|
|
350
|
-
|
|
351
388
|
def trace_real
|
|
352
|
-
|
|
389
|
+
raw_id = encode_identifier_octets
|
|
390
|
+
encoded_id = raw_id.unpack1('w*')
|
|
353
391
|
data_length = raw_data.length
|
|
354
|
-
encoded_length =
|
|
355
|
-
|
|
392
|
+
encoded_length = raw_length.unpack1('w*')
|
|
393
|
+
parts = [msg_type(raw_id.unpack1('H*').to_i(16), encoded_id)]
|
|
394
|
+
msg = parts.reject(&:empty?).join(' ')
|
|
395
|
+
msg << ", #{length_specifier(data_length, encoded_length)}"
|
|
356
396
|
msg << trace_data
|
|
357
397
|
end
|
|
358
398
|
|
|
359
399
|
def trace_data(data=nil)
|
|
360
|
-
byte_count = 0
|
|
361
400
|
data ||= raw_data
|
|
362
|
-
|
|
363
|
-
lines =
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
end
|
|
370
|
-
str[compute_trace_index(byte_count, 3), 2] = '%02x' % byte
|
|
371
|
-
str[compute_trace_index(byte_count, 1, 49)] = byte.between?(32, 126) ? byte.chr : '.'
|
|
372
|
-
byte_count += 1
|
|
401
|
+
format_string = data.size > 65_535 ? '%08X' : '%04X'
|
|
402
|
+
lines = data.bytes.each_slice(16).map.with_index do |chunk, index|
|
|
403
|
+
offset = format_string % (index * 16)
|
|
404
|
+
hex = chunk.map { |b| '%02x' % b }.join(' ')
|
|
405
|
+
hex_padded = hex.ljust(47) # 16*2 hex digits + 15 spaces
|
|
406
|
+
ascii = chunk.map { |b| (32..126).cover?(b) ? b.chr : '.' }.join
|
|
407
|
+
" #{offset} #{hex_padded} |#{ascii}|"
|
|
373
408
|
end
|
|
374
|
-
lines.
|
|
375
|
-
end
|
|
376
|
-
|
|
377
|
-
def trace_format_new_data_line(count)
|
|
378
|
-
head_line = RASN1.tracer.indent(RASN1.tracer.tracing_level + 1)
|
|
379
|
-
("\n#{head_line}%04x " % count) << ' ' * 68
|
|
380
|
-
end
|
|
381
|
-
|
|
382
|
-
def compute_trace_index(byte_count, byte_count_mul=1, offset=0)
|
|
383
|
-
base_idx = 7 + RASN1.tracer.indent(RASN1.tracer.tracing_level + 1).length
|
|
384
|
-
base_idx + offset + (byte_count % 16) * byte_count_mul
|
|
409
|
+
"\n#{lines.join("\n")}"
|
|
385
410
|
end
|
|
386
411
|
|
|
387
412
|
def unpack(binstr)
|
|
@@ -389,22 +414,16 @@ module RASN1
|
|
|
389
414
|
end
|
|
390
415
|
|
|
391
416
|
def asn1_class_to_s
|
|
392
|
-
asn1_class
|
|
417
|
+
asn1_class.to_s.upcase
|
|
393
418
|
end
|
|
394
419
|
|
|
395
|
-
def msg_type(no_id: false)
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
else
|
|
403
|
-
+''
|
|
404
|
-
end
|
|
405
|
-
msg << colorize_class(type)
|
|
406
|
-
msg << " #{colorize_attribute('OPTIONAL')}" if optional?
|
|
407
|
-
msg
|
|
420
|
+
def msg_type(raw_id=nil, _encoded_id=nil, no_id: false)
|
|
421
|
+
parts = []
|
|
422
|
+
parts << colorize_name(name) unless name.nil?
|
|
423
|
+
real_id = no_id ? nil : raw_id || id
|
|
424
|
+
parts << colorize_id(id, asn1_class_to_s) if real_id
|
|
425
|
+
parts << colorize_class(type, real_id, *self.attributes)
|
|
426
|
+
parts.reject(&:empty?).join(' ')
|
|
408
427
|
end
|
|
409
428
|
|
|
410
429
|
def pc_bit
|
|
@@ -417,22 +436,32 @@ module RASN1
|
|
|
417
436
|
end
|
|
418
437
|
end
|
|
419
438
|
|
|
420
|
-
def
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
439
|
+
def universal?
|
|
440
|
+
@asn1_class == :universal
|
|
441
|
+
end
|
|
442
|
+
|
|
443
|
+
def common_inspect(level=0, color: false)
|
|
444
|
+
begin_colorizer(color)
|
|
445
|
+
parts = []
|
|
446
|
+
parts << "(#{model})" if model
|
|
447
|
+
parts << colorize_name(name) if name
|
|
448
|
+
parts << colorize_id(id, asn1_class_to_s) if id && !universal?
|
|
449
|
+
class_name = colorize_class(type, nil, *self.attributes)
|
|
450
|
+
class_name += ':' if constructed?
|
|
451
|
+
parts << class_name
|
|
452
|
+
end_colorizer
|
|
453
|
+
"#{" " * level}" + parts.reject(&:empty?).join(' ').to_s
|
|
428
454
|
end
|
|
429
455
|
|
|
430
456
|
def inspect_value
|
|
431
|
-
if value?
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
457
|
+
str = if value?
|
|
458
|
+
colorize_value(value.inspect)
|
|
459
|
+
else
|
|
460
|
+
colorize_nil('(NO VALUE)')
|
|
461
|
+
end
|
|
462
|
+
|
|
463
|
+
str += colorize_default(@default) if @default
|
|
464
|
+
str
|
|
436
465
|
end
|
|
437
466
|
|
|
438
467
|
def value_to_der
|
|
@@ -466,7 +495,7 @@ module RASN1
|
|
|
466
495
|
end
|
|
467
496
|
|
|
468
497
|
# handle undocumented option +:tag_value+, used internally by
|
|
469
|
-
# {
|
|
498
|
+
# {RASN2.parse} to parse non-universal class tags.
|
|
470
499
|
def set_tag(options) # rubocop:disable Naming/AccessorMethodName
|
|
471
500
|
@constructed = options[:constructed]
|
|
472
501
|
if options[:explicit]
|
|
@@ -586,6 +615,8 @@ module RASN1
|
|
|
586
615
|
elsif !@default.nil?
|
|
587
616
|
@value = @default
|
|
588
617
|
else
|
|
618
|
+
return true if self.instance_of?(Tag)
|
|
619
|
+
|
|
589
620
|
raise_id_error(der)
|
|
590
621
|
end
|
|
591
622
|
false
|
|
@@ -638,18 +669,24 @@ module RASN1
|
|
|
638
669
|
|
|
639
670
|
def raise_id_error(der)
|
|
640
671
|
msg = name.nil? ? +'' : "#{name}: "
|
|
641
|
-
msg << "Expected #{self2name} but
|
|
672
|
+
msg << "Expected #{self2name} but got #{der2name(der)}"
|
|
642
673
|
|
|
643
674
|
raise ASN1Error, msg
|
|
644
675
|
end
|
|
645
676
|
|
|
646
677
|
def self2name
|
|
647
|
-
|
|
678
|
+
parts = [asn1_class.to_s.upcase]
|
|
679
|
+
parts << (constructed? ? 'CONSTRUCTED' : 'PRIMITIVE').to_s
|
|
648
680
|
if implicit? || explicit?
|
|
649
|
-
|
|
681
|
+
parts << '0x%X (0x%s)' % [id, bin2hex(encode_identifier_octets)]
|
|
650
682
|
else
|
|
651
|
-
|
|
683
|
+
parts << self.class.type.to_s
|
|
652
684
|
end
|
|
685
|
+
parts.reject(&:empty?).join(' ')
|
|
686
|
+
end
|
|
687
|
+
|
|
688
|
+
def indent(input, by=2)
|
|
689
|
+
input.split("\n").map { |line| (" " * by) + line }.join("\n")
|
|
653
690
|
end
|
|
654
691
|
|
|
655
692
|
def der2name(der)
|
|
@@ -658,11 +695,12 @@ module RASN1
|
|
|
658
695
|
asn1_class, pc, id, id_size = Types.decode_identifier_octets(der)
|
|
659
696
|
name = "#{asn1_class.to_s.upcase} #{pc.to_s.upcase}"
|
|
660
697
|
type = find_type(id)
|
|
661
|
-
name << " #{type.nil? ?
|
|
698
|
+
name << " #{type.nil? ? bin2hex(der[0...id_size]).to_s : type.encoded_type}"
|
|
662
699
|
end
|
|
663
700
|
|
|
664
701
|
def find_type(id)
|
|
665
702
|
Types.constants.map { |c| Types.const_get(c) }
|
|
703
|
+
.grep(Class)
|
|
666
704
|
.select { |klass| klass < Primitive || klass < Constructed }
|
|
667
705
|
.find { |klass| id == klass::ID }
|
|
668
706
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
module
|
|
3
|
+
module RASN2
|
|
4
4
|
module Types
|
|
5
5
|
# ASN.1 Bit String
|
|
6
6
|
# @author Sylvain Daubert
|
|
@@ -34,11 +34,8 @@ module RASN1
|
|
|
34
34
|
end
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
def inspect(level=0)
|
|
40
|
-
str = common_inspect(level)
|
|
41
|
-
str << " #{value.inspect} (bit length: #{bit_length})"
|
|
37
|
+
def inspect_value
|
|
38
|
+
"(bit length: #{bit_length}): #{value.inspect}"
|
|
42
39
|
end
|
|
43
40
|
|
|
44
41
|
# Same as {Base#can_build?} but also check bit_length
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
module
|
|
3
|
+
module RASN2
|
|
4
4
|
module Types
|
|
5
5
|
# ASN.1 Boolean
|
|
6
6
|
# @author Sylvain Daubert
|
|
@@ -50,7 +50,7 @@ module RASN1
|
|
|
50
50
|
def trace_data
|
|
51
51
|
return super if explicit?
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
" #{colorize_bool(raw_data != "\x00".b, raw_data)}"
|
|
54
54
|
end
|
|
55
55
|
end
|
|
56
56
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
module
|
|
3
|
+
module RASN2
|
|
4
4
|
module Types
|
|
5
5
|
# A ASN.1 CHOICE is a choice between different types.
|
|
6
6
|
#
|
|
@@ -25,7 +25,7 @@ module RASN1
|
|
|
25
25
|
#
|
|
26
26
|
# == Parse a CHOICE
|
|
27
27
|
# Parsing a CHOICE set {#chosen} and set value to chosen type. If parsed string does
|
|
28
|
-
# not contain a type from CHOICE, a {
|
|
28
|
+
# not contain a type from CHOICE, a {RASN2::ASN1Error} is raised.
|
|
29
29
|
# str = "\x04\x03abc"
|
|
30
30
|
# choice.parse! str
|
|
31
31
|
# choice.chosen # => 2
|
|
@@ -126,12 +126,12 @@ module RASN1
|
|
|
126
126
|
|
|
127
127
|
# @param [::Integer] level
|
|
128
128
|
# @return [String]
|
|
129
|
-
def inspect(level=0)
|
|
129
|
+
def inspect(level=0, color: true)
|
|
130
130
|
str = common_inspect(level)
|
|
131
131
|
str << if defined?(@chosen) && value?
|
|
132
|
-
|
|
132
|
+
@value[@chosen].inspect(level + 1)
|
|
133
133
|
else
|
|
134
|
-
'
|
|
134
|
+
'not chosen!'
|
|
135
135
|
end
|
|
136
136
|
end
|
|
137
137
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
module
|
|
3
|
+
module RASN2
|
|
4
4
|
module Types
|
|
5
|
-
# Mixin to add constraints on a
|
|
5
|
+
# Mixin to add constraints on a RASN2 type.
|
|
6
6
|
# Should not be used directly but through {Types.define_type}.
|
|
7
7
|
# @version 0.11.0
|
|
8
8
|
# @author Sylvain Daubert
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
module
|
|
3
|
+
module RASN2
|
|
4
4
|
module Types
|
|
5
5
|
# @abstract This class SHOULD be used as base class for all ASN.1 primitive
|
|
6
6
|
# types.
|
|
@@ -23,29 +23,6 @@ module RASN1
|
|
|
23
23
|
(el.value.respond_to?(:empty?) ? !el.value.empty? : !el.value.nil?))
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
|
-
|
|
27
|
-
# @param [::Integer] level (default: 0)
|
|
28
|
-
# @return [String]
|
|
29
|
-
def inspect(level=0)
|
|
30
|
-
case @value
|
|
31
|
-
when Array
|
|
32
|
-
str = common_inspect(level)
|
|
33
|
-
str << "\n"
|
|
34
|
-
level = level.abs + 1
|
|
35
|
-
@value.each do |item|
|
|
36
|
-
case item
|
|
37
|
-
when Base, Model, Wrapper
|
|
38
|
-
str << "#{item.inspect(level)}\n"
|
|
39
|
-
else
|
|
40
|
-
str << ' ' * level
|
|
41
|
-
str << "#{item.inspect}\n"
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
str
|
|
45
|
-
else
|
|
46
|
-
super
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
26
|
end
|
|
50
27
|
end
|
|
51
28
|
end
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
module
|
|
3
|
+
module RASN2
|
|
4
4
|
module Types
|
|
5
5
|
# ASN.1 Enumerated
|
|
6
6
|
#
|
|
7
7
|
# An enumerated type permits to assign names to integer values. It may be defined
|
|
8
8
|
# different ways:
|
|
9
|
-
# enum =
|
|
10
|
-
# enum =
|
|
9
|
+
# enum = RASN2::Types::Enumerated.new(enum: { 'a' => 0, 'b' => 1, 'c' => 2 })
|
|
10
|
+
# enum = RASN2::Types::Enumerated.new(enum: { a: 0, b: 1, c: 2 })
|
|
11
11
|
# Its value should be setting as an Integer or a String/symbol:
|
|
12
12
|
# enum.value = :b
|
|
13
13
|
# enum.value = 1 # equivalent to :b
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
module
|
|
3
|
+
module RASN2
|
|
4
4
|
module Types
|
|
5
5
|
# ASN.1 IA5 String
|
|
6
6
|
# @author Sylvain Daubert
|
|
@@ -16,6 +16,10 @@ module RASN1
|
|
|
16
16
|
def self.type
|
|
17
17
|
'IA5String'
|
|
18
18
|
end
|
|
19
|
+
|
|
20
|
+
def inspect_value
|
|
21
|
+
colorize_value(@value.inspect)
|
|
22
|
+
end
|
|
19
23
|
end
|
|
20
24
|
end
|
|
21
25
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
module
|
|
3
|
+
module RASN2
|
|
4
4
|
module Types
|
|
5
5
|
# ASN.1 Integer
|
|
6
6
|
# @author Sylvain Daubert
|
|
@@ -155,8 +155,9 @@ module RASN1
|
|
|
155
155
|
|
|
156
156
|
def trace_data
|
|
157
157
|
return super if explicit?
|
|
158
|
+
|
|
158
159
|
i = der_to_int_value(raw_data)
|
|
159
|
-
return " #{int_with_hex(i, raw_data.unpack1('
|
|
160
|
+
return " #{int_with_hex(i, raw_data.unpack1('w*'))}" if @enum.empty?
|
|
160
161
|
|
|
161
162
|
v = int_to_enum(i, check_enum: false)
|
|
162
163
|
" #{colorize_enum(v, raw_data)}"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
module
|
|
3
|
+
module RASN2
|
|
4
4
|
module Types
|
|
5
5
|
# ASN.1 Null
|
|
6
6
|
# @author Sylvain Daubert
|
|
@@ -9,10 +9,11 @@ module RASN1
|
|
|
9
9
|
ID = 0x05
|
|
10
10
|
|
|
11
11
|
# @return [String]
|
|
12
|
-
def inspect(level=0)
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
def inspect(level=0, color: true)
|
|
13
|
+
begin_colorizer(color)
|
|
14
|
+
result = common_inspect(level)
|
|
15
|
+
end_colorizer
|
|
16
|
+
result
|
|
16
17
|
end
|
|
17
18
|
|
|
18
19
|
# @return [Boolean]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
module
|
|
3
|
+
module RASN2
|
|
4
4
|
module Types
|
|
5
5
|
# ASN.1 Octet String
|
|
6
6
|
#
|
|
@@ -15,11 +15,8 @@ module RASN1
|
|
|
15
15
|
# OctetString id value
|
|
16
16
|
ID = 4
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def inspect(level=0)
|
|
21
|
-
str = common_inspect(level)
|
|
22
|
-
str << " #{value.inspect}"
|
|
18
|
+
def inspect_value
|
|
19
|
+
value.inspect
|
|
23
20
|
end
|
|
24
21
|
|
|
25
22
|
# Make string value from +der+ string. Force encoding to UTF-8
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
module
|
|
3
|
+
module RASN2
|
|
4
4
|
module Types
|
|
5
5
|
# ASN.1 sequence
|
|
6
6
|
#
|
|
@@ -13,15 +13,15 @@ module RASN1
|
|
|
13
13
|
# house [1] IMPLICIT INTEGER DEFAULT 0
|
|
14
14
|
# }
|
|
15
15
|
# do:
|
|
16
|
-
# seq =
|
|
16
|
+
# seq = RASN2::Types::Sequence.new
|
|
17
17
|
# seq.value = [
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
18
|
+
# RASN2::Types::Integer.new
|
|
19
|
+
# RASN2::Types::Integer.new(explicit: 0, optional: true),
|
|
20
|
+
# RASN2::Types::Integer.new(implicit: 1, default: 0)
|
|
21
21
|
# ]
|
|
22
22
|
#
|
|
23
23
|
# A sequence may also be used without value to not parse sequence content:
|
|
24
|
-
# seq =
|
|
24
|
+
# seq = RASN2::Types::Sequence.new(:seq)
|
|
25
25
|
# seq.parse!(der_string)
|
|
26
26
|
# seq.value # => String
|
|
27
27
|
# @author Sylvain Daubert
|