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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
|
# coding: ASCII-8BIT
using ASN1Kit::BERString
module ASN1Kit
class Type
CONSTRAINT = nil
class Tag < Struct.new(:tagging, :tag_class, :tag_number)
def acceptable_ber_header?(str, offset = 0)
tc, tn, constructed, hlen, len = str.get_object(offset)
if tc == tag_class && tn == tag_number
[constructed, hlen, len]
else
nil
end
end
end
TAG = nil
class << self
def tagging!(tagging, tag_class, tag_number)
const_set(:TAG, Tag.new(tagging, tag_class, tag_number))
end
def asn1_tag(tagging, tag_class, tag_number)
const_set(:TAG, Tag.new(tagging, tag_class, tag_number))
end
def asn1_alias(name)
instance_variable_set(:@alias, name)
end
def tagging(tagging, tag_class, tag_number)
ret = Class.new(self)
ret.tagging!(tagging, tag_class, tag_number)
ret
end
def from_ber(str)
list = self::TAG.acceptable_ber_header?(str) or
raise EncodingError, "invalid object: %p, %p, %p, %p, %p" % str.get_object(str)
constructed, hlen, len = list
if self::TAG.tagging == :EXPLICIT
raise EncodingError, "invalid EXPLICIT tagging encoding" unless constructed
c = self
while c = c.superclass
raise EncodingError, "invalid EXPLICIT tagging: %p" % self unless c < ASN1Kit::Type
break unless c::TAG.equal?(self::TAG)
end
list_inner = c::TAG.acceptable_ber_header?(str, hlen) or
raise EncodingError, "invalid EXPLICIT tagging inner object"
end
if len == 0x80
from_ber_content(str, 0, nil, true)
else
from_ber_content(str, 0, len, constructed)
end
end
private def from_ber_content(str, offset, len, constructed)
raise NotImplementedError, "BER decoding for %p not implemented" % self
end
def check_ber_header(str, expect_con = false, pos: 0)
tc, con, tn, len, pos = str.get_object(pos)
if tc != self::TAG.tag_class || expect_con != con || tn != self::TAG.tag_number
raise "invalid object: %p, %p, %p, %p, %p" % [tc, con, tn, len, pos]
end
[len, pos]
end
def builtin?
false
end
def inspect_abbrev
defined?(@alias) ? "<#{@alias}>" : inspect
end
def inspect
name = defined?(@alias) ? "(#{@alias}) " : ""
type_ancestors = ancestors.drop(1).select { |x| x < Type }
baseclass = type_ancestors.find { |x| x.instance_variable_defined?(:@alias) }
baseclass ||= type_ancestors.reverse_each.find { |x| x < ASN1Kit::Type }
if baseclass
if self::TAG != baseclass::TAG
prefix = "["
if self::TAG.tag_class != :CONTEXT_SPECIFIC
prefix << self::TAG.tag_class.to_s << " "
end
prefix << self::TAG.tag_number.to_s << "] "
end
bname = baseclass.instance_variable_get(:@alias) || baseclass.name
end
if body = inspect_inner
"<#{name}#{prefix}#{bname} #{body}>"
else
"<#{name}#{prefix}#{bname}>"
end
end
private def inspect_inner() nil end
end
def to_der
raise NotImplementedError, "DER encoding for %p not implemented" % self.class
end
private def der_header(len, encoding = :primitive)
"".put_object(self.class::TAG.tag_class, self.class::TAG.tag_number, len, encoding)
end
def cast_to(type)
raise TypeError, "casting %p value into %p undefined" % [self.class, type]
end
def inspect_abbrev
defined?(@alias) ? "{#{@alias}}" : inspect
end
def inspect
name = defined?(@alias) ? "(#{@alias})" : ""
if body = inspect_inner
"{#{name}#{self.class.inspect_abbrev} #{body}}"
else
"{#{name}#{self.class.inspect_abbrev}}"
end
end
def initialize_copy(orig)
super
# UGHH; Duplicated instances should not have an alias
remove_instance_variable(:@alias) if defined?(@alias)
end
private def inspect_inner() defined?(@value) ? @value.inspect : nil end
end
end
module ASN1Kit::Internal
module CompileType
refine ASN1Kit::Type.singleton_class do
def _compile_fixup(state)
end
attr_reader :alias
def alias=(value)
unreachable if defined?(@alias)
@alias = value
end
end
refine ASN1Kit::Type do
def _compile_fixup(state)
end
attr_reader :alias
def alias=(value)
unreachable if defined?(@alias)
@alias = value
end
end
end
end
require_relative "types/boolean"
require_relative "types/integer"
require_relative "types/bit_string"
require_relative "types/octet_string"
require_relative "types/null"
require_relative "types/object_identifier"
require_relative "types/real"
require_relative "types/enumerated"
require_relative "types/relative_oid"
require_relative "types/sequence"
require_relative "types/sequence_of"
require_relative "types/set"
require_relative "types/set_of"
require_relative "types/choice"
require_relative "types/character_string_types"
require_relative "types/useful_types"
|