1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
# coding: ASCII-8BIT
class ASN1Kit::Sequence < ASN1Kit::Type
asn1_tag :IMPLICIT, :UNIVERSAL, 16
asn1_alias "SEQUENCE"
class ComponentType
attr_reader :name, :type, :default
def optional?
@optional
end
def initialize(name, type, default: nil, optional: false)
@name = name
@type = type
@default = default
@optional = optional
end
def inspect
str = "#{name} #{type.inspect_abbrev}"
str << " DEFAULT #{default.inspect_abbrev}" if default
str << " OPTIONAL" if optional?
str
end
end
class << self
def [](*component_types)
ret = Class.new(self)
hash = component_types.map { |c| [c.name, c] }.to_h
ret.const_set(:COMPONENT_TYPES, hash)
ret
end
def component_types
self::COMPONENT_TYPES.keys
end
def component_type(name)
self::COMPONENT_TYPES[name]&.type
end
private def inspect_inner
ctypes = self::COMPONENT_TYPES.values.map { |c| c.inspect }.join(", ")
"{ #{ctypes} }"
end
# def pretty_print(q)
# nil
# end
def from_ber(str)
ssize = str.bytesize
, pos = check_ber_header(str, constructed: true)
hash = {}
last = nil
self::COMPONENT_TYPES.each do |c|
last ||= str.get_object(pos)
if c.optional?
next if a
end
end
end
end
def initialize(value)
unless defined?(self.class::COMPONENT_TYPES)
raise "unable to instantiate uninitialized SEQUENCE"
end
@value = value
end
def [](name)
unless self.class::COMPONENT_TYPES[name]
raise ArgumentError, "invalid component type name: %p" % name
end
@value[name]
end
def to_der
content = self.class::COMPONENT_TYPES.map { |name, type, opts|
next nil unless @value[name]
@value[name].to_der
}.compact.join
der_header(content.bytesize, :constructed) << content
end
end
module ASN1Kit::Internal::CompileSequence
refine ASN1Kit::Sequence::ComponentType do
attr_writer :name, :type, :default, :optional
end
refine ASN1Kit::Sequence.singleton_class do
def _compile_fixup(state)
self::COMPONENT_TYPES.each do |name, c|
if c.type.is_a?(ASN1Kit::Internal::TypeReference)
c.type = c.type.unwrap(state)
end
state.resolve(c.type)
if c.default
c.default.type = c.type # opts[:default] may be still TypeReference at this time
c.default = c.default.unwrap(state)
state.resolve(c.default)
end
end
end
end
refine ASN1Kit::Sequence do
def _compile_fixup(state)
@value.transform_values! do |value|
value = value.unwrap(state)
state.resolve(value)
value
end
end
end
end
|