rasn2 0.16.0 → 1.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 → rasn2}/errors.rb +2 -2
- data/lib/{rasn1 → rasn2}/helpers/colorize.rb +1 -1
- data/lib/{rasn1 → rasn2}/model.rb +10 -10
- data/lib/{rasn1 → rasn2}/schema_parser.rb +9 -9
- data/lib/{rasn1 → rasn2}/tracer.rb +12 -12
- data/lib/{rasn1 → rasn2}/types/any.rb +1 -1
- data/lib/{rasn1 → rasn2}/types/base.rb +11 -11
- data/lib/{rasn1 → rasn2}/types/bit_string.rb +1 -1
- data/lib/{rasn1 → rasn2}/types/bmp_string.rb +1 -1
- data/lib/{rasn1 → rasn2}/types/boolean.rb +1 -1
- data/lib/{rasn1 → rasn2}/types/choice.rb +2 -2
- data/lib/{rasn1 → rasn2}/types/constrained.rb +2 -2
- data/lib/{rasn1 → rasn2}/types/constructed.rb +1 -1
- 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 +1 -1
- data/lib/{rasn1 → rasn2}/types/integer.rb +1 -1
- data/lib/{rasn1 → rasn2}/types/null.rb +1 -1
- 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 +1 -1
- 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 +10 -10
- 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 +1 -1
- 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 +3 -3
- data/lib/{rasn1 → rasn2}/value_notation.rb +5 -5
- data/lib/rasn2/version.rb +6 -0
- data/lib/{rasn1 → rasn2}/wrapper.rb +8 -8
- data/lib/{rasn1.rb → rasn2.rb} +13 -13
- metadata +40 -40
- data/lib/rasn1/version.rb +0 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c9744f6f89db9eccc56949cfaa1be37d919f1c12cbea2178d8ffd05d6a526e72
|
|
4
|
+
data.tar.gz: ea3fc33186e718dd636948ba6eeeb915beac90617c1736a265770daeb2a45a15
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 58299aa777a6c80d63c6f8faed939ac638804a7a28a25e83e431a78391564a9138902252b0ebe1ebd7c46a168311f008c5540a23590f905d1c78598ad05bfe31
|
|
7
|
+
data.tar.gz: 78c1496c6792b9542ab1d76c6134d12cc9cd6e8c4e55c18a62fcb5574ed6d40c7c9179cf5bf66b1f277dc9f27ee507c885fc4d5b3dbd52894d42c409d08b1206
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
module
|
|
3
|
+
module RASN2
|
|
4
4
|
# Base error class
|
|
5
5
|
class Error < StandardError; end
|
|
6
6
|
|
|
@@ -19,7 +19,7 @@ module RASN1
|
|
|
19
19
|
class EnumeratedError < Error; end
|
|
20
20
|
|
|
21
21
|
# CHOICE error: {Types::Choice#chosen} not set
|
|
22
|
-
class ChoiceError <
|
|
22
|
+
class ChoiceError < RASN2::Error
|
|
23
23
|
# @param [Types::Base] object
|
|
24
24
|
def initialize(object)
|
|
25
25
|
@object = object
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
module
|
|
3
|
+
module RASN2
|
|
4
4
|
# @abstract
|
|
5
5
|
# {Model} class is a base class to define ASN.1 models.
|
|
6
6
|
# == Create a simple ASN.1 model
|
|
@@ -11,7 +11,7 @@ module RASN1
|
|
|
11
11
|
# house [1] EXPLICIT INTEGER DEFAULT 0
|
|
12
12
|
# }
|
|
13
13
|
# you may create your model like this:
|
|
14
|
-
# class Record <
|
|
14
|
+
# class Record < RASN2::Model
|
|
15
15
|
# sequence(:record,
|
|
16
16
|
# content: [integer(:id),
|
|
17
17
|
# integer(:room, implicit: 0, optional: true),
|
|
@@ -20,7 +20,7 @@ module RASN1
|
|
|
20
20
|
#
|
|
21
21
|
# Since 0.17.0, content may also be defined through a block. This is strictly
|
|
22
22
|
# equivalent to the +:content+ option:
|
|
23
|
-
# class Record <
|
|
23
|
+
# class Record < RASN2::Model
|
|
24
24
|
# sequence :record do
|
|
25
25
|
# integer :id
|
|
26
26
|
# integer :room, implicit: 0, optional: true
|
|
@@ -28,7 +28,7 @@ module RASN1
|
|
|
28
28
|
# end
|
|
29
29
|
# end
|
|
30
30
|
# Blocks may be nested, and may use all model helpers (+#model+, +#wrapper+, +#sequence_of+, ...):
|
|
31
|
-
# class PersonnelRecord <
|
|
31
|
+
# class PersonnelRecord < RASN2::Model
|
|
32
32
|
# sequence :personnelRecord do
|
|
33
33
|
# utf8_string :name
|
|
34
34
|
# utf8_string :title
|
|
@@ -43,7 +43,7 @@ module RASN1
|
|
|
43
43
|
#
|
|
44
44
|
# === Parse a DER-encoded string
|
|
45
45
|
# record = Record.parse(der_string)
|
|
46
|
-
# record[:id] # =>
|
|
46
|
+
# record[:id] # => RASN2::Types::Integer
|
|
47
47
|
# record[:id].value # => Integer
|
|
48
48
|
# record[:id].to_i # => Integer
|
|
49
49
|
# record[:id].asn1_class # => Symbol
|
|
@@ -61,7 +61,7 @@ module RASN1
|
|
|
61
61
|
#
|
|
62
62
|
# == Create a more complex model
|
|
63
63
|
# Models may be nested. For example:
|
|
64
|
-
# class Record2 <
|
|
64
|
+
# class Record2 < RASN2::Model
|
|
65
65
|
# sequence(:record2,
|
|
66
66
|
# content: [boolean(:rented, default: false),
|
|
67
67
|
# model(:a_record, Record)])
|
|
@@ -74,7 +74,7 @@ module RASN1
|
|
|
74
74
|
# or like this:
|
|
75
75
|
# record2 = Record2.new(rented: true, a_record: { id: 65537, room: 43 })
|
|
76
76
|
# Same model, using a block:
|
|
77
|
-
# class Record2 <
|
|
77
|
+
# class Record2 < RASN2::Model
|
|
78
78
|
# sequence :record2 do
|
|
79
79
|
# boolean :rented, default: false
|
|
80
80
|
# model :a_record, Record
|
|
@@ -193,7 +193,7 @@ module RASN1
|
|
|
193
193
|
|
|
194
194
|
# Update options of root element.
|
|
195
195
|
# May be used when subclassing.
|
|
196
|
-
# class Model1 <
|
|
196
|
+
# class Model1 < RASN2::Model
|
|
197
197
|
# sequence :seq, implicit: 0,
|
|
198
198
|
# content: [bool(:bool), integer(:int)]
|
|
199
199
|
# end
|
|
@@ -587,10 +587,10 @@ module RASN1
|
|
|
587
587
|
# @return [Object,nil]
|
|
588
588
|
# @return [Object,nil]
|
|
589
589
|
# @example
|
|
590
|
-
# class MyModel1 <
|
|
590
|
+
# class MyModel1 < RASN2::Model
|
|
591
591
|
# sequence('seq', content: [boolean('boolean'), integer('int')])
|
|
592
592
|
# end
|
|
593
|
-
# class MyModel2 <
|
|
593
|
+
# class MyModel2 < RASN2::Model
|
|
594
594
|
# sequence('root', content: [sequence_of('list', MyModel1)])
|
|
595
595
|
# end
|
|
596
596
|
# model = MyModel2.new
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
module
|
|
3
|
+
module RASN2
|
|
4
4
|
# Parser for ASN.1 text schema definitions.
|
|
5
5
|
#
|
|
6
6
|
# Parses ASN.1 module definitions and generates {Model} subclasses from them.
|
|
7
7
|
#
|
|
8
8
|
# @example Parse a schema file
|
|
9
|
-
# models =
|
|
10
|
-
# # => { 'PersonnelRecord' => PersonnelRecord (class <
|
|
9
|
+
# models = RASN2::SchemaParser.parse_file('path/to/schema.asn')
|
|
10
|
+
# # => { 'PersonnelRecord' => PersonnelRecord (class < RASN2::Model) }
|
|
11
11
|
#
|
|
12
12
|
# @example Parse a schema string
|
|
13
13
|
# schema = <<~ASN1
|
|
@@ -19,12 +19,12 @@ module RASN1
|
|
|
19
19
|
# }
|
|
20
20
|
# END
|
|
21
21
|
# ASN1
|
|
22
|
-
# models =
|
|
22
|
+
# models = RASN2::SchemaParser.parse(schema)
|
|
23
23
|
#
|
|
24
24
|
# @author rickmark
|
|
25
25
|
# @since 0.16.0
|
|
26
26
|
module SchemaParser
|
|
27
|
-
# ASN.1 type name to
|
|
27
|
+
# ASN.1 type name to RASN2 type DSL method mapping
|
|
28
28
|
TYPE_MAP = {
|
|
29
29
|
'BOOLEAN' => :boolean,
|
|
30
30
|
'INTEGER' => :integer,
|
|
@@ -48,7 +48,7 @@ module RASN1
|
|
|
48
48
|
CONSTRUCTED_TYPES = %w[SEQUENCE SET].freeze
|
|
49
49
|
|
|
50
50
|
# Error raised when parsing an ASN.1 schema fails
|
|
51
|
-
class ParseError <
|
|
51
|
+
class ParseError < RASN2::Error; end
|
|
52
52
|
|
|
53
53
|
class << self
|
|
54
54
|
# Parse an ASN.1 schema from a file and generate Model classes.
|
|
@@ -348,7 +348,7 @@ module RASN1
|
|
|
348
348
|
# Build a single Model subclass
|
|
349
349
|
# @return [Class]
|
|
350
350
|
def build_model_class(type_name, type_def, mod, existing_models, namespace)
|
|
351
|
-
klass = Class.new(
|
|
351
|
+
klass = Class.new(RASN2::Model)
|
|
352
352
|
|
|
353
353
|
root_name = type_name.gsub(/([a-z])([A-Z])/, '\1_\2').gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').downcase.to_sym
|
|
354
354
|
|
|
@@ -445,14 +445,14 @@ module RASN1
|
|
|
445
445
|
# (end of private section)
|
|
446
446
|
end
|
|
447
447
|
|
|
448
|
-
# Convert an ASN.1 type name to the corresponding
|
|
448
|
+
# Convert an ASN.1 type name to the corresponding RASN2 Model DSL method symbol
|
|
449
449
|
# @param [String] type_name
|
|
450
450
|
# @return [Symbol, nil]
|
|
451
451
|
def self.type_to_method(type_name)
|
|
452
452
|
TYPE_MAP[type_name]
|
|
453
453
|
end
|
|
454
454
|
|
|
455
|
-
# Convert an ASN.1 type name to the corresponding
|
|
455
|
+
# Convert an ASN.1 type name to the corresponding RASN2::Types class
|
|
456
456
|
# @param [String] type_name
|
|
457
457
|
# @return [Class, nil]
|
|
458
458
|
def self.type_to_class(type_name)
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require 'rainbow'
|
|
4
4
|
|
|
5
|
-
module
|
|
5
|
+
module RASN2
|
|
6
6
|
# @private
|
|
7
7
|
class Tracer
|
|
8
8
|
# @return [IO]
|
|
@@ -49,19 +49,19 @@ module RASN1
|
|
|
49
49
|
end
|
|
50
50
|
end
|
|
51
51
|
|
|
52
|
-
# Trace
|
|
52
|
+
# Trace RASN2 parsing to +io+.
|
|
53
53
|
# All parsing methods called in block are traced to +io+. Each ASN.1 element is
|
|
54
54
|
# traced in a line showing element's id, its length and its data.
|
|
55
55
|
# @param [IO] io
|
|
56
56
|
# @param [Boolean] color enable colorized output using pastel gem (requires pastel to be installed)
|
|
57
57
|
# @example
|
|
58
|
-
#
|
|
59
|
-
#
|
|
58
|
+
# RASN2.trace do
|
|
59
|
+
# RASN2.parse("\x02\x01\x01") # puts "INTEGER id: 2 (0x02), len: 1 (0x01), data: 0x01"
|
|
60
60
|
# end
|
|
61
|
-
#
|
|
61
|
+
# RASN2.parse("\x01\x01\xff") # puts nothing onto STDOUT
|
|
62
62
|
# @example with color
|
|
63
|
-
#
|
|
64
|
-
#
|
|
63
|
+
# RASN2.trace(color: true) do
|
|
64
|
+
# RASN2.parse("\x02\x01\x01") # same output but with ANSI colors
|
|
65
65
|
# end
|
|
66
66
|
# @return [void]
|
|
67
67
|
def self.trace(io=$stdout, color: false)
|
|
@@ -142,7 +142,7 @@ module RASN1
|
|
|
142
142
|
# Parse +der+ with tracing abillity
|
|
143
143
|
# @see #parse!
|
|
144
144
|
def parse_with_tracing(der, ber: false)
|
|
145
|
-
|
|
145
|
+
RASN2.tracer.trace(self.trace)
|
|
146
146
|
parse_without_tracing(der, ber: ber)
|
|
147
147
|
end
|
|
148
148
|
end
|
|
@@ -166,9 +166,9 @@ module RASN1
|
|
|
166
166
|
# @private
|
|
167
167
|
# der_to_value +der+ with tracing abillity
|
|
168
168
|
def der_to_value_with_tracing(der, ber: false)
|
|
169
|
-
|
|
169
|
+
RASN2.tracer.tracing_level += 1
|
|
170
170
|
der_to_value_without_tracing(der, ber: ber)
|
|
171
|
-
|
|
171
|
+
RASN2.tracer.tracing_level -= 1
|
|
172
172
|
end
|
|
173
173
|
end
|
|
174
174
|
|
|
@@ -191,9 +191,9 @@ module RASN1
|
|
|
191
191
|
# @private
|
|
192
192
|
# der_to_value +der+ with tracing abillity
|
|
193
193
|
def der_to_value_with_tracing(der, ber: false)
|
|
194
|
-
|
|
194
|
+
RASN2.tracer.tracing_level += 1
|
|
195
195
|
der_to_value_without_tracing(der, ber: ber)
|
|
196
|
-
|
|
196
|
+
RASN2.tracer.tracing_level -= 1
|
|
197
197
|
end
|
|
198
198
|
end
|
|
199
199
|
end
|
|
@@ -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,15 +34,15 @@ 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
48
|
# Allowed ASN.1 classes
|
|
@@ -57,7 +57,7 @@ module RASN1
|
|
|
57
57
|
tracer ? tracer.colorize(msg) : Rainbow.new.wrap(msg)
|
|
58
58
|
end
|
|
59
59
|
|
|
60
|
-
include
|
|
60
|
+
include RASN2::Helpers::Colorize
|
|
61
61
|
|
|
62
62
|
# Binary mask to get class
|
|
63
63
|
# @private
|
|
@@ -85,7 +85,7 @@ module RASN1
|
|
|
85
85
|
private :raw_data, :raw_length
|
|
86
86
|
|
|
87
87
|
def tracer
|
|
88
|
-
::
|
|
88
|
+
::RASN2.tracer
|
|
89
89
|
end
|
|
90
90
|
|
|
91
91
|
# Get ASN.1 type
|
|
@@ -375,12 +375,12 @@ module RASN1
|
|
|
375
375
|
end
|
|
376
376
|
|
|
377
377
|
def trace_format_new_data_line(count)
|
|
378
|
-
head_line =
|
|
378
|
+
head_line = RASN2.tracer.indent(RASN2.tracer.tracing_level + 1)
|
|
379
379
|
("\n#{head_line}%04x " % count) << ' ' * 68
|
|
380
380
|
end
|
|
381
381
|
|
|
382
382
|
def compute_trace_index(byte_count, byte_count_mul=1, offset=0)
|
|
383
|
-
base_idx = 7 +
|
|
383
|
+
base_idx = 7 + RASN2.tracer.indent(RASN2.tracer.tracing_level + 1).length
|
|
384
384
|
base_idx + offset + (byte_count % 16) * byte_count_mul
|
|
385
385
|
end
|
|
386
386
|
|
|
@@ -466,7 +466,7 @@ module RASN1
|
|
|
466
466
|
end
|
|
467
467
|
|
|
468
468
|
# handle undocumented option +:tag_value+, used internally by
|
|
469
|
-
# {
|
|
469
|
+
# {RASN2.parse} to parse non-universal class tags.
|
|
470
470
|
def set_tag(options) # rubocop:disable Naming/AccessorMethodName
|
|
471
471
|
@constructed = options[:constructed]
|
|
472
472
|
if options[:explicit]
|
|
@@ -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
|
|
@@ -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,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 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
|
|
@@ -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 OF
|
|
6
6
|
#
|
|
@@ -11,28 +11,28 @@ module RASN1
|
|
|
11
11
|
# Integers ::= SEQUENCE OF INTEGER
|
|
12
12
|
# do:
|
|
13
13
|
# # Create a SEQUENCE OF INTEGER
|
|
14
|
-
# seqof =
|
|
14
|
+
# seqof = RASN2::Types::SequenceOf.new(RASN2::Types::Integer)
|
|
15
15
|
# # Set integer values
|
|
16
|
-
# seqof.value = [1, 2, 3, 4].map { |i|
|
|
17
|
-
# seqof << 5 # infer a
|
|
16
|
+
# seqof.value = [1, 2, 3, 4].map { |i| RASN2::Types::Integer.new(value: i) }
|
|
17
|
+
# seqof << 5 # infer a RASN2::Types::Integer with given value
|
|
18
18
|
#
|
|
19
19
|
# == Use with {Constructed} types
|
|
20
20
|
# SEQUENCE OF may be used to create sequence of composed types. For example:
|
|
21
|
-
# composed_type =
|
|
22
|
-
# commposed_type.value = [
|
|
23
|
-
#
|
|
24
|
-
# seqof =
|
|
21
|
+
# composed_type = RASN2::Types::Sequence.new
|
|
22
|
+
# commposed_type.value = [RASN2::Types::Integer,
|
|
23
|
+
# RASN2::Types::OctetString]
|
|
24
|
+
# seqof = RASN2::Types::SequenceOf.new(composed_type)
|
|
25
25
|
# seqof << [0, 'data0']
|
|
26
26
|
# seqof << [1, 'data1']
|
|
27
27
|
#
|
|
28
28
|
# == Use with {Model}
|
|
29
29
|
# SEQUENCE OF may also be used with a Model type:
|
|
30
|
-
# class MyModel <
|
|
30
|
+
# class MyModel < RASN2::Model
|
|
31
31
|
# sequence :seq,
|
|
32
32
|
# content: [boolean(:bool), integer(:int)]
|
|
33
33
|
# end
|
|
34
34
|
#
|
|
35
|
-
# seqof =
|
|
35
|
+
# seqof = RASN2::Types::SequenceOf.new(:record, MyModel)
|
|
36
36
|
# # set values
|
|
37
37
|
# seqof << { bool: true, int: 12 }
|
|
38
38
|
# seqof << { bool: false, int: 65535 }
|
|
@@ -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 set
|
|
6
6
|
#
|
|
@@ -13,11 +13,11 @@ module RASN1
|
|
|
13
13
|
# house [1] IMPLICIT INTEGER DEFAULT 0
|
|
14
14
|
# }
|
|
15
15
|
# do:
|
|
16
|
-
# set =
|
|
16
|
+
# set = RASN2::Types::Set.new
|
|
17
17
|
# set.value = [
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
18
|
+
# RASN2::Types::Integer
|
|
19
|
+
# RASN2::Types::Integer(explicit: 0, optional: true),
|
|
20
|
+
# RASN2::Types::Integer(implicit: 1, default: 0)
|
|
21
21
|
# ]
|
|
22
22
|
# @author Sylvain Daubert
|
|
23
23
|
class Set < Sequence
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require_relative 'types/constrained'
|
|
4
4
|
|
|
5
|
-
module
|
|
5
|
+
module RASN2
|
|
6
6
|
# This modules is a namesapce for all ASN.1 type classes.
|
|
7
7
|
# @author Sylvain Daubert
|
|
8
8
|
module Types
|
|
@@ -89,7 +89,7 @@ module RASN1
|
|
|
89
89
|
# This new type may have a constraint defines on it.
|
|
90
90
|
# @param [Symbol,String] name new type name. Must start with a capital letter.
|
|
91
91
|
# @param [Types::Base] from class from which inherits
|
|
92
|
-
# @param [Module] in_module module in which creates new type (default to {
|
|
92
|
+
# @param [Module] in_module module in which creates new type (default to {RASN2::Types})
|
|
93
93
|
# @return [Class] newly created class
|
|
94
94
|
# @yieldparam [Object] value value to set to type, or infered at parsing
|
|
95
95
|
# @yieldreturn [Boolean]
|
|
@@ -98,7 +98,7 @@ module RASN1
|
|
|
98
98
|
# @example
|
|
99
99
|
# # Define a new UInt32 type
|
|
100
100
|
# # UInt32 ::= INTEGER (0 .. 4294967295)
|
|
101
|
-
#
|
|
101
|
+
# RASN2::Types.define_type('UInt32', from: RASN2::Types::Integer) do |value|
|
|
102
102
|
# (value >= 0) && (value < 2**32)
|
|
103
103
|
# end
|
|
104
104
|
def self.define_type(name, from:, in_module: self, &block)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
module
|
|
3
|
+
module RASN2
|
|
4
4
|
# Support for ASN.1 value notation (text representation of ASN.1 data instances).
|
|
5
5
|
#
|
|
6
6
|
# ASN.1 value notation allows defining values for ASN.1 types in a human-readable
|
|
@@ -16,8 +16,8 @@ module RASN1
|
|
|
16
16
|
# to generate such text from {Model} instances.
|
|
17
17
|
#
|
|
18
18
|
# @example Parse a value notation string
|
|
19
|
-
# models =
|
|
20
|
-
# record =
|
|
19
|
+
# models = RASN2::SchemaParser.parse_file('schema.asn')
|
|
20
|
+
# record = RASN2::ValueNotation.parse(
|
|
21
21
|
# File.read('instance.asn'),
|
|
22
22
|
# models: models
|
|
23
23
|
# )
|
|
@@ -25,13 +25,13 @@ module RASN1
|
|
|
25
25
|
#
|
|
26
26
|
# @example Generate value notation from a model
|
|
27
27
|
# record = PersonnelRecord.new(name: 'John Doe', title: 'Engineer', age: 30, employed: true)
|
|
28
|
-
# text =
|
|
28
|
+
# text = RASN2::ValueNotation.emit(record, name: 'myPerson', type_name: 'PersonnelRecord')
|
|
29
29
|
#
|
|
30
30
|
# @author rickmark
|
|
31
31
|
# @since 0.17.0
|
|
32
32
|
module ValueNotation
|
|
33
33
|
# Error raised when parsing or emitting value notation fails
|
|
34
|
-
class Error <
|
|
34
|
+
class Error < RASN2::Error; end
|
|
35
35
|
|
|
36
36
|
class << self
|
|
37
37
|
# Parse an ASN.1 value notation string and populate a model instance.
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
require 'delegate'
|
|
4
4
|
|
|
5
|
-
module
|
|
5
|
+
module RASN2
|
|
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
|
|
9
|
+
# This class may be used to wrap another RASN2 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
12
|
# * explicitly wrap an object (i.e wrap the object in another explicit ASN.1 tag),
|
|
@@ -14,15 +14,15 @@ module RASN1
|
|
|
14
14
|
#
|
|
15
15
|
# @example Wrapping object
|
|
16
16
|
# # object to wrap
|
|
17
|
-
# int =
|
|
17
|
+
# int = RASN2::Types::Integer.new(implicit: 1) # its tag is 0x81
|
|
18
18
|
# # simple wrapper, change an option
|
|
19
|
-
# wrapper =
|
|
19
|
+
# wrapper = RASN2::Wrapper.new(int, default: 1)
|
|
20
20
|
# # implicit wrapper
|
|
21
|
-
# wrapper =
|
|
21
|
+
# wrapper = RASN2::Wrapper.new(int, implicit: 3) # wrapped int tag is now 0x83
|
|
22
22
|
# # explicit wrapper
|
|
23
|
-
# wrapper =
|
|
23
|
+
# wrapper = RASN2::Wrapper.new(int, explicit: 4) # int tag is always 0x81, but it is wrapped in a 0x84 tag
|
|
24
24
|
# @example Wrapping a choice to make it recursive
|
|
25
|
-
# class RecursiveChoice <
|
|
25
|
+
# class RecursiveChoice < RASN2::Model
|
|
26
26
|
# choice :choice,
|
|
27
27
|
# content: [
|
|
28
28
|
# integer(:value, implicit: 1),
|
|
@@ -78,7 +78,7 @@ module RASN1
|
|
|
78
78
|
@element_options_to_merge = opts
|
|
79
79
|
@options = {}
|
|
80
80
|
end
|
|
81
|
-
raise
|
|
81
|
+
raise RASN2::Error, 'Cannot be implicit and explicit' if explicit? && implicit?
|
|
82
82
|
|
|
83
83
|
super(element)
|
|
84
84
|
end
|
data/lib/{rasn1.rb → rasn2.rb}
RENAMED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative '
|
|
4
|
-
require_relative '
|
|
5
|
-
require_relative '
|
|
6
|
-
require_relative '
|
|
7
|
-
require_relative '
|
|
8
|
-
require_relative '
|
|
9
|
-
require_relative '
|
|
10
|
-
require_relative '
|
|
11
|
-
require_relative '
|
|
3
|
+
require_relative 'rasn2/version'
|
|
4
|
+
require_relative 'rasn2/errors'
|
|
5
|
+
require_relative 'rasn2/helpers/colorize'
|
|
6
|
+
require_relative 'rasn2/types'
|
|
7
|
+
require_relative 'rasn2/model'
|
|
8
|
+
require_relative 'rasn2/wrapper'
|
|
9
|
+
require_relative 'rasn2/tracer'
|
|
10
|
+
require_relative 'rasn2/schema_parser'
|
|
11
|
+
require_relative 'rasn2/value_notation'
|
|
12
12
|
|
|
13
13
|
# Constrained types
|
|
14
|
-
require_relative '
|
|
14
|
+
require_relative 'rasn2/types/visible_string'
|
|
15
15
|
|
|
16
16
|
# Rasn1 is a pure ruby library to parse, decode and encode ASN.1 data.
|
|
17
17
|
# @author Sylvain Daubert
|
|
18
|
-
module
|
|
18
|
+
module RASN2
|
|
19
19
|
# @private
|
|
20
20
|
CONTAINER_CLASSES = [Types::Sequence, Types::Set].freeze
|
|
21
21
|
|
|
@@ -36,10 +36,10 @@ module RASN1
|
|
|
36
36
|
size = type.parse!(der, ber: ber)
|
|
37
37
|
|
|
38
38
|
if CONTAINER_CLASSES.include?(type.class)
|
|
39
|
-
|
|
39
|
+
RASN2.tracer.tracing_level += 1 unless RASN2.tracer.nil?
|
|
40
40
|
content = self.parse(type.value)
|
|
41
41
|
type.value = content.is_a?(Array) ? content : [content]
|
|
42
|
-
|
|
42
|
+
RASN2.tracer.tracing_level -= 1 unless RASN2.tracer.nil?
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
result << type
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rasn2
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: '1.0'
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- LemonTree55
|
|
@@ -39,7 +39,7 @@ dependencies:
|
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: 0.2.5
|
|
41
41
|
description: |
|
|
42
|
-
|
|
42
|
+
Rasn2 is a pure ruby ASN.1 library. It may encode and decode DER and BER
|
|
43
43
|
encodings.
|
|
44
44
|
email:
|
|
45
45
|
- lenontree@proton.me
|
|
@@ -52,43 +52,43 @@ extra_rdoc_files:
|
|
|
52
52
|
files:
|
|
53
53
|
- LICENSE
|
|
54
54
|
- README.md
|
|
55
|
-
- lib/
|
|
56
|
-
- lib/
|
|
57
|
-
- lib/
|
|
58
|
-
- lib/
|
|
59
|
-
- lib/
|
|
60
|
-
- lib/
|
|
61
|
-
- lib/
|
|
62
|
-
- lib/
|
|
63
|
-
- lib/
|
|
64
|
-
- lib/
|
|
65
|
-
- lib/
|
|
66
|
-
- lib/
|
|
67
|
-
- lib/
|
|
68
|
-
- lib/
|
|
69
|
-
- lib/
|
|
70
|
-
- lib/
|
|
71
|
-
- lib/
|
|
72
|
-
- lib/
|
|
73
|
-
- lib/
|
|
74
|
-
- lib/
|
|
75
|
-
- lib/
|
|
76
|
-
- lib/
|
|
77
|
-
- lib/
|
|
78
|
-
- lib/
|
|
79
|
-
- lib/
|
|
80
|
-
- lib/
|
|
81
|
-
- lib/
|
|
82
|
-
- lib/
|
|
83
|
-
- lib/
|
|
84
|
-
- lib/
|
|
85
|
-
- lib/
|
|
86
|
-
- lib/
|
|
87
|
-
- lib/
|
|
88
|
-
- lib/
|
|
89
|
-
- lib/
|
|
90
|
-
- lib/
|
|
91
|
-
- lib/
|
|
55
|
+
- lib/rasn2.rb
|
|
56
|
+
- lib/rasn2/errors.rb
|
|
57
|
+
- lib/rasn2/helpers/colorize.rb
|
|
58
|
+
- lib/rasn2/model.rb
|
|
59
|
+
- lib/rasn2/schema_parser.rb
|
|
60
|
+
- lib/rasn2/tracer.rb
|
|
61
|
+
- lib/rasn2/types.rb
|
|
62
|
+
- lib/rasn2/types/any.rb
|
|
63
|
+
- lib/rasn2/types/base.rb
|
|
64
|
+
- lib/rasn2/types/bit_string.rb
|
|
65
|
+
- lib/rasn2/types/bmp_string.rb
|
|
66
|
+
- lib/rasn2/types/boolean.rb
|
|
67
|
+
- lib/rasn2/types/choice.rb
|
|
68
|
+
- lib/rasn2/types/constrained.rb
|
|
69
|
+
- lib/rasn2/types/constructed.rb
|
|
70
|
+
- lib/rasn2/types/enumerated.rb
|
|
71
|
+
- lib/rasn2/types/generalized_time.rb
|
|
72
|
+
- lib/rasn2/types/ia5_string.rb
|
|
73
|
+
- lib/rasn2/types/integer.rb
|
|
74
|
+
- lib/rasn2/types/null.rb
|
|
75
|
+
- lib/rasn2/types/numeric_string.rb
|
|
76
|
+
- lib/rasn2/types/object_id.rb
|
|
77
|
+
- lib/rasn2/types/octet_string.rb
|
|
78
|
+
- lib/rasn2/types/primitive.rb
|
|
79
|
+
- lib/rasn2/types/printable_string.rb
|
|
80
|
+
- lib/rasn2/types/sequence.rb
|
|
81
|
+
- lib/rasn2/types/sequence_of.rb
|
|
82
|
+
- lib/rasn2/types/set.rb
|
|
83
|
+
- lib/rasn2/types/set_of.rb
|
|
84
|
+
- lib/rasn2/types/tag.rb
|
|
85
|
+
- lib/rasn2/types/universal_string.rb
|
|
86
|
+
- lib/rasn2/types/utc_time.rb
|
|
87
|
+
- lib/rasn2/types/utf8_string.rb
|
|
88
|
+
- lib/rasn2/types/visible_string.rb
|
|
89
|
+
- lib/rasn2/value_notation.rb
|
|
90
|
+
- lib/rasn2/version.rb
|
|
91
|
+
- lib/rasn2/wrapper.rb
|
|
92
92
|
homepage: https://github.com/lemontree55/rasn1
|
|
93
93
|
licenses:
|
|
94
94
|
- MIT
|
|
@@ -99,7 +99,7 @@ metadata:
|
|
|
99
99
|
documentation_uri: https://www.rubydoc.info/gems/rasn1
|
|
100
100
|
rdoc_options:
|
|
101
101
|
- "--title"
|
|
102
|
-
-
|
|
102
|
+
- Rasn2 - A pure ruby ASN.1 library
|
|
103
103
|
- "--main"
|
|
104
104
|
- README.md
|
|
105
105
|
- "--inline-source"
|