1
|
|
|
# Base classes for ASN.1 types |
2
|
|
|
import sys |
3
|
|
|
from pyasn1.type import constraint, tagmap |
4
|
|
|
from pyasn1 import error |
5
|
|
|
|
6
|
|
|
class Asn1Item: pass |
7
|
|
|
|
8
|
|
|
class Asn1ItemBase(Asn1Item): |
9
|
|
|
# Set of tags for this ASN.1 type |
10
|
|
|
tagSet = () |
11
|
|
|
|
12
|
|
|
# A list of constraint.Constraint instances for checking values |
13
|
|
|
subtypeSpec = constraint.ConstraintsIntersection() |
14
|
|
|
|
15
|
|
|
# Used for ambiguous ASN.1 types identification |
16
|
|
|
typeId = None |
17
|
|
|
|
18
|
|
|
def __init__(self, tagSet=None, subtypeSpec=None): |
19
|
|
|
if tagSet is None: |
20
|
|
|
self._tagSet = self.tagSet |
21
|
|
|
else: |
22
|
|
|
self._tagSet = tagSet |
23
|
|
|
if subtypeSpec is None: |
24
|
|
|
self._subtypeSpec = self.subtypeSpec |
25
|
|
|
else: |
26
|
|
|
self._subtypeSpec = subtypeSpec |
27
|
|
|
|
28
|
|
|
def _verifySubtypeSpec(self, value, idx=None): |
29
|
|
|
self._subtypeSpec(value, idx) |
30
|
|
|
|
31
|
|
|
def getSubtypeSpec(self): return self._subtypeSpec |
32
|
|
|
|
33
|
|
|
def getTagSet(self): return self._tagSet |
34
|
|
|
def getEffectiveTagSet(self): return self._tagSet # used by untagged types |
35
|
|
|
def getTagMap(self): return tagmap.TagMap({self._tagSet: self}) |
36
|
|
|
|
37
|
|
|
def isSameTypeWith(self, other): |
38
|
|
|
return self is other or \ |
39
|
|
|
self._tagSet == other.getTagSet() and \ |
40
|
|
|
self._subtypeSpec == other.getSubtypeSpec() |
41
|
|
|
def isSuperTypeOf(self, other): |
42
|
|
|
"""Returns true if argument is a ASN1 subtype of ourselves""" |
43
|
|
|
return self._tagSet.isSuperTagSetOf(other.getTagSet()) and \ |
44
|
|
|
self._subtypeSpec.isSuperTypeOf(other.getSubtypeSpec()) |
45
|
|
|
|
46
|
|
|
class __NoValue: |
47
|
|
|
def __getattr__(self, attr): |
48
|
|
|
raise error.PyAsn1Error('No value for %s()' % attr) |
49
|
|
|
noValue = __NoValue() |
50
|
|
|
|
51
|
|
|
# Base class for "simple" ASN.1 objects. These are immutable. |
52
|
|
|
class AbstractSimpleAsn1Item(Asn1ItemBase): |
53
|
|
|
defaultValue = noValue |
54
|
|
|
def __init__(self, value=None, tagSet=None, subtypeSpec=None): |
55
|
|
|
Asn1ItemBase.__init__(self, tagSet, subtypeSpec) |
56
|
|
|
if value is None or value is noValue: |
57
|
|
|
value = self.defaultValue |
58
|
|
|
if value is None or value is noValue: |
59
|
|
|
self.__hashedValue = value = noValue |
60
|
|
|
else: |
61
|
|
|
value = self.prettyIn(value) |
62
|
|
|
self._verifySubtypeSpec(value) |
63
|
|
|
self.__hashedValue = hash(value) |
64
|
|
|
self._value = value |
65
|
|
|
self._len = None |
66
|
|
|
|
67
|
|
|
def __repr__(self): |
68
|
|
|
if self._value is noValue: |
69
|
|
|
return self.__class__.__name__ + '()' |
70
|
|
|
else: |
71
|
|
|
return self.__class__.__name__ + '(' + self.prettyOut(self._value) + ')' |
72
|
|
|
def __str__(self): return str(self._value) |
73
|
|
|
def __eq__(self, other): |
74
|
|
|
return self is other and True or self._value == other |
75
|
|
|
def __ne__(self, other): return self._value != other |
76
|
|
|
def __lt__(self, other): return self._value < other |
77
|
|
|
def __le__(self, other): return self._value <= other |
78
|
|
|
def __gt__(self, other): return self._value > other |
79
|
|
|
def __ge__(self, other): return self._value >= other |
80
|
|
|
if sys.version_info[0] <= 2: |
81
|
|
|
def __nonzero__(self): return bool(self._value) |
82
|
|
|
else: |
83
|
|
|
def __bool__(self): return bool(self._value) |
84
|
|
|
def __hash__(self): return self.__hashedValue |
85
|
|
|
|
86
|
|
|
def clone(self, value=None, tagSet=None, subtypeSpec=None): |
87
|
|
|
if value is None and tagSet is None and subtypeSpec is None: |
88
|
|
|
return self |
89
|
|
|
if value is None: |
90
|
|
|
value = self._value |
91
|
|
|
if tagSet is None: |
92
|
|
|
tagSet = self._tagSet |
93
|
|
|
if subtypeSpec is None: |
94
|
|
|
subtypeSpec = self._subtypeSpec |
95
|
|
|
return self.__class__(value, tagSet, subtypeSpec) |
96
|
|
|
|
97
|
|
|
def subtype(self, value=None, implicitTag=None, explicitTag=None, |
98
|
|
|
subtypeSpec=None): |
99
|
|
|
if value is None: |
100
|
|
|
value = self._value |
101
|
|
|
if implicitTag is not None: |
102
|
|
|
tagSet = self._tagSet.tagImplicitly(implicitTag) |
103
|
|
|
elif explicitTag is not None: |
104
|
|
|
tagSet = self._tagSet.tagExplicitly(explicitTag) |
105
|
|
|
else: |
106
|
|
|
tagSet = self._tagSet |
107
|
|
|
if subtypeSpec is None: |
108
|
|
|
subtypeSpec = self._subtypeSpec |
109
|
|
|
else: |
110
|
|
|
subtypeSpec = subtypeSpec + self._subtypeSpec |
111
|
|
|
return self.__class__(value, tagSet, subtypeSpec) |
112
|
|
|
|
113
|
|
|
def prettyIn(self, value): return value |
114
|
|
|
def prettyOut(self, value): return str(value) |
115
|
|
|
|
116
|
|
|
def prettyPrint(self, scope=0): return self.prettyOut(self._value) |
117
|
|
|
# XXX Compatibility stub |
118
|
|
|
def prettyPrinter(self, scope=0): return self.prettyPrint(scope) |
119
|
|
|
|
120
|
|
|
# |
121
|
|
|
# Constructed types: |
122
|
|
|
# * There are five of them: Sequence, SequenceOf/SetOf, Set and Choice |
123
|
|
|
# * ASN1 types and values are represened by Python class instances |
124
|
|
|
# * Value initialization is made for defaulted components only |
125
|
|
|
# * Primary method of component addressing is by-position. Data model for base |
126
|
|
|
# type is Python sequence. Additional type-specific addressing methods |
127
|
|
|
# may be implemented for particular types. |
128
|
|
|
# * SequenceOf and SetOf types do not implement any additional methods |
129
|
|
|
# * Sequence, Set and Choice types also implement by-identifier addressing |
130
|
|
|
# * Sequence, Set and Choice types also implement by-asn1-type (tag) addressing |
131
|
|
|
# * Sequence and Set types may include optional and defaulted |
132
|
|
|
# components |
133
|
|
|
# * Constructed types hold a reference to component types used for value |
134
|
|
|
# verification and ordering. |
135
|
|
|
# * Component type is a scalar type for SequenceOf/SetOf types and a list |
136
|
|
|
# of types for Sequence/Set/Choice. |
137
|
|
|
# |
138
|
|
|
|
139
|
|
|
class AbstractConstructedAsn1Item(Asn1ItemBase): |
140
|
|
|
componentType = None |
141
|
|
|
sizeSpec = constraint.ConstraintsIntersection() |
142
|
|
|
def __init__(self, componentType=None, tagSet=None, |
143
|
|
|
subtypeSpec=None, sizeSpec=None): |
144
|
|
|
Asn1ItemBase.__init__(self, tagSet, subtypeSpec) |
145
|
|
|
if componentType is None: |
146
|
|
|
self._componentType = self.componentType |
147
|
|
|
else: |
148
|
|
|
self._componentType = componentType |
149
|
|
|
if sizeSpec is None: |
150
|
|
|
self._sizeSpec = self.sizeSpec |
151
|
|
|
else: |
152
|
|
|
self._sizeSpec = sizeSpec |
153
|
|
|
self._componentValues = [] |
154
|
|
|
self._componentValuesSet = 0 |
155
|
|
|
|
156
|
|
|
def __repr__(self): |
157
|
|
|
r = self.__class__.__name__ + '()' |
158
|
|
|
for idx in range(len(self._componentValues)): |
159
|
|
|
if self._componentValues[idx] is None: |
160
|
|
|
continue |
161
|
|
|
r = r + '.setComponentByPosition(%s, %s)' % ( |
162
|
|
|
idx, repr(self._componentValues[idx]) |
163
|
|
|
) |
164
|
|
|
return r |
165
|
|
|
|
166
|
|
|
def __eq__(self, other): |
167
|
|
|
return self is other and True or self._componentValues == other |
168
|
|
|
def __ne__(self, other): return self._componentValues != other |
169
|
|
|
def __lt__(self, other): return self._componentValues < other |
170
|
|
|
def __le__(self, other): return self._componentValues <= other |
171
|
|
|
def __gt__(self, other): return self._componentValues > other |
172
|
|
|
def __ge__(self, other): return self._componentValues >= other |
173
|
|
|
if sys.version_info[0] <= 2: |
174
|
|
|
def __nonzero__(self): return bool(self._componentValues) |
175
|
|
|
else: |
176
|
|
|
def __bool__(self): return bool(self._componentValues) |
177
|
|
|
|
178
|
|
|
def getComponentTagMap(self): |
179
|
|
|
raise error.PyAsn1Error('Method not implemented') |
180
|
|
|
|
181
|
|
|
def _cloneComponentValues(self, myClone, cloneValueFlag): pass |
182
|
|
|
|
183
|
|
|
def clone(self, tagSet=None, subtypeSpec=None, sizeSpec=None, |
184
|
|
|
cloneValueFlag=None): |
185
|
|
|
if tagSet is None: |
186
|
|
|
tagSet = self._tagSet |
187
|
|
|
if subtypeSpec is None: |
188
|
|
|
subtypeSpec = self._subtypeSpec |
189
|
|
|
if sizeSpec is None: |
190
|
|
|
sizeSpec = self._sizeSpec |
191
|
|
|
r = self.__class__(self._componentType, tagSet, subtypeSpec, sizeSpec) |
192
|
|
|
if cloneValueFlag: |
193
|
|
|
self._cloneComponentValues(r, cloneValueFlag) |
194
|
|
|
return r |
195
|
|
|
|
196
|
|
|
def subtype(self, implicitTag=None, explicitTag=None, subtypeSpec=None, |
197
|
|
|
sizeSpec=None, cloneValueFlag=None): |
198
|
|
|
if implicitTag is not None: |
199
|
|
|
tagSet = self._tagSet.tagImplicitly(implicitTag) |
200
|
|
|
elif explicitTag is not None: |
201
|
|
|
tagSet = self._tagSet.tagExplicitly(explicitTag) |
202
|
|
|
else: |
203
|
|
|
tagSet = self._tagSet |
204
|
|
|
if subtypeSpec is None: |
205
|
|
|
subtypeSpec = self._subtypeSpec |
206
|
|
|
else: |
207
|
|
|
subtypeSpec = subtypeSpec + self._subtypeSpec |
208
|
|
|
if sizeSpec is None: |
209
|
|
|
sizeSpec = self._sizeSpec |
210
|
|
|
else: |
211
|
|
|
sizeSpec = sizeSpec + self._sizeSpec |
212
|
|
|
r = self.__class__(self._componentType, tagSet, subtypeSpec, sizeSpec) |
213
|
|
|
if cloneValueFlag: |
214
|
|
|
self._cloneComponentValues(r, cloneValueFlag) |
215
|
|
|
return r |
216
|
|
|
|
217
|
|
|
def _verifyComponent(self, idx, value): pass |
218
|
|
|
|
219
|
|
|
def verifySizeSpec(self): self._sizeSpec(self) |
220
|
|
|
|
221
|
|
|
def getComponentByPosition(self, idx): |
222
|
|
|
raise error.PyAsn1Error('Method not implemented') |
223
|
|
|
def setComponentByPosition(self, idx, value, verifyConstraints=True): |
224
|
|
|
raise error.PyAsn1Error('Method not implemented') |
225
|
|
|
|
226
|
|
|
def getComponentType(self): return self._componentType |
227
|
|
|
|
228
|
|
|
def __getitem__(self, idx): return self.getComponentByPosition(idx) |
229
|
|
|
def __setitem__(self, idx, value): self.setComponentByPosition(idx, value) |
230
|
|
|
|
231
|
|
|
def __len__(self): return len(self._componentValues) |
232
|
|
|
|
233
|
|
|
def clear(self): |
234
|
|
|
self._componentValues = [] |
235
|
|
|
self._componentValuesSet = 0 |
236
|
|
|
|
237
|
|
|
def setDefaultComponents(self): pass |
238
|
|
|
|