1#
2# This file is part of pyasn1 software.
3#
4# Copyright (c) 2005-2020, Ilya Etingof <etingof@gmail.com>
5# License: https://pyasn1.readthedocs.io/en/latest/license.html
6#
7import sys
8
9from pyasn1 import error
10from pyasn1.type import tag
11from pyasn1.type import univ
12
13__all__ = ['NumericString', 'PrintableString', 'TeletexString', 'T61String', 'VideotexString',
14 'IA5String', 'GraphicString', 'VisibleString', 'ISO646String',
15 'GeneralString', 'UniversalString', 'BMPString', 'UTF8String']
16
17NoValue = univ.NoValue
18noValue = univ.noValue
19
20
21class AbstractCharacterString(univ.OctetString):
22 """Creates |ASN.1| schema or value object.
23
24 |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`,
25 its objects are immutable and duck-type :class:`bytes`.
26 When used in octet-stream context, |ASN.1| type assumes
27 "|encoding|" encoding.
28
29 Keyword Args
30 ------------
31 value: :class:`str`, :class:`bytes` or |ASN.1| object
32 :class:`str`, alternatively :class:`bytes`
33 representing octet-stream of serialised unicode string
34 (note `encoding` parameter) or |ASN.1| class instance.
35 If `value` is not given, schema object will be created.
36
37 tagSet: :py:class:`~pyasn1.type.tag.TagSet`
38 Object representing non-default ASN.1 tag(s)
39
40 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
41 Object representing non-default ASN.1 subtype constraint(s). Constraints
42 verification for |ASN.1| type occurs automatically on object
43 instantiation.
44
45 encoding: :py:class:`str`
46 Unicode codec ID to encode/decode
47 :class:`str` the payload when |ASN.1| object is used
48 in octet-stream context.
49
50 Raises
51 ------
52 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error
53 On constraint violation or bad initializer.
54 """
55
56 def __str__(self):
57 return str(self._value)
58
59 def __bytes__(self):
60 try:
61 return self._value.encode(self.encoding)
62 except UnicodeEncodeError as exc:
63 raise error.PyAsn1UnicodeEncodeError(
64 "Can't encode string '%s' with codec "
65 "%s" % (self._value, self.encoding), exc
66 )
67
68 def prettyIn(self, value):
69 try:
70 if isinstance(value, str):
71 return value
72 elif isinstance(value, bytes):
73 return value.decode(self.encoding)
74 elif isinstance(value, (tuple, list)):
75 return self.prettyIn(bytes(value))
76 elif isinstance(value, univ.OctetString):
77 return value.asOctets().decode(self.encoding)
78 else:
79 return str(value)
80
81 except (UnicodeDecodeError, LookupError) as exc:
82 raise error.PyAsn1UnicodeDecodeError(
83 "Can't decode string '%s' with codec "
84 "%s" % (value, self.encoding), exc
85 )
86
87 def asOctets(self, padding=True):
88 return bytes(self)
89
90 def asNumbers(self, padding=True):
91 return tuple(bytes(self))
92
93 #
94 # See OctetString.prettyPrint() for the explanation
95 #
96
97 def prettyOut(self, value):
98 return value
99
100 def prettyPrint(self, scope=0):
101 # first see if subclass has its own .prettyOut()
102 value = self.prettyOut(self._value)
103
104 if value is not self._value:
105 return value
106
107 return AbstractCharacterString.__str__(self)
108
109 def __reversed__(self):
110 return reversed(self._value)
111
112
113class NumericString(AbstractCharacterString):
114 __doc__ = AbstractCharacterString.__doc__
115
116 #: Set (on class, not on instance) or return a
117 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
118 #: associated with |ASN.1| type.
119 tagSet = AbstractCharacterString.tagSet.tagImplicitly(
120 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 18)
121 )
122 encoding = 'us-ascii'
123
124 # Optimization for faster codec lookup
125 typeId = AbstractCharacterString.getTypeId()
126
127
128class PrintableString(AbstractCharacterString):
129 __doc__ = AbstractCharacterString.__doc__
130
131 #: Set (on class, not on instance) or return a
132 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
133 #: associated with |ASN.1| type.
134 tagSet = AbstractCharacterString.tagSet.tagImplicitly(
135 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 19)
136 )
137 encoding = 'us-ascii'
138
139 # Optimization for faster codec lookup
140 typeId = AbstractCharacterString.getTypeId()
141
142
143class TeletexString(AbstractCharacterString):
144 __doc__ = AbstractCharacterString.__doc__
145
146 #: Set (on class, not on instance) or return a
147 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
148 #: associated with |ASN.1| type.
149 tagSet = AbstractCharacterString.tagSet.tagImplicitly(
150 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 20)
151 )
152 encoding = 'iso-8859-1'
153
154 # Optimization for faster codec lookup
155 typeId = AbstractCharacterString.getTypeId()
156
157
158class T61String(TeletexString):
159 __doc__ = TeletexString.__doc__
160
161 # Optimization for faster codec lookup
162 typeId = AbstractCharacterString.getTypeId()
163
164
165class VideotexString(AbstractCharacterString):
166 __doc__ = AbstractCharacterString.__doc__
167
168 #: Set (on class, not on instance) or return a
169 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
170 #: associated with |ASN.1| type.
171 tagSet = AbstractCharacterString.tagSet.tagImplicitly(
172 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 21)
173 )
174 encoding = 'iso-8859-1'
175
176 # Optimization for faster codec lookup
177 typeId = AbstractCharacterString.getTypeId()
178
179
180class IA5String(AbstractCharacterString):
181 __doc__ = AbstractCharacterString.__doc__
182
183 #: Set (on class, not on instance) or return a
184 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
185 #: associated with |ASN.1| type.
186 tagSet = AbstractCharacterString.tagSet.tagImplicitly(
187 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 22)
188 )
189 encoding = 'us-ascii'
190
191 # Optimization for faster codec lookup
192 typeId = AbstractCharacterString.getTypeId()
193
194
195class GraphicString(AbstractCharacterString):
196 __doc__ = AbstractCharacterString.__doc__
197
198 #: Set (on class, not on instance) or return a
199 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
200 #: associated with |ASN.1| type.
201 tagSet = AbstractCharacterString.tagSet.tagImplicitly(
202 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 25)
203 )
204 encoding = 'iso-8859-1'
205
206 # Optimization for faster codec lookup
207 typeId = AbstractCharacterString.getTypeId()
208
209
210class VisibleString(AbstractCharacterString):
211 __doc__ = AbstractCharacterString.__doc__
212
213 #: Set (on class, not on instance) or return a
214 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
215 #: associated with |ASN.1| type.
216 tagSet = AbstractCharacterString.tagSet.tagImplicitly(
217 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 26)
218 )
219 encoding = 'us-ascii'
220
221 # Optimization for faster codec lookup
222 typeId = AbstractCharacterString.getTypeId()
223
224
225class ISO646String(VisibleString):
226 __doc__ = VisibleString.__doc__
227
228 # Optimization for faster codec lookup
229 typeId = AbstractCharacterString.getTypeId()
230
231class GeneralString(AbstractCharacterString):
232 __doc__ = AbstractCharacterString.__doc__
233
234 #: Set (on class, not on instance) or return a
235 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
236 #: associated with |ASN.1| type.
237 tagSet = AbstractCharacterString.tagSet.tagImplicitly(
238 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 27)
239 )
240 encoding = 'iso-8859-1'
241
242 # Optimization for faster codec lookup
243 typeId = AbstractCharacterString.getTypeId()
244
245
246class UniversalString(AbstractCharacterString):
247 __doc__ = AbstractCharacterString.__doc__
248
249 #: Set (on class, not on instance) or return a
250 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
251 #: associated with |ASN.1| type.
252 tagSet = AbstractCharacterString.tagSet.tagImplicitly(
253 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 28)
254 )
255 encoding = "utf-32-be"
256
257 # Optimization for faster codec lookup
258 typeId = AbstractCharacterString.getTypeId()
259
260
261class BMPString(AbstractCharacterString):
262 __doc__ = AbstractCharacterString.__doc__
263
264 #: Set (on class, not on instance) or return a
265 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
266 #: associated with |ASN.1| type.
267 tagSet = AbstractCharacterString.tagSet.tagImplicitly(
268 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 30)
269 )
270 encoding = "utf-16-be"
271
272 # Optimization for faster codec lookup
273 typeId = AbstractCharacterString.getTypeId()
274
275
276class UTF8String(AbstractCharacterString):
277 __doc__ = AbstractCharacterString.__doc__
278
279 #: Set (on class, not on instance) or return a
280 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
281 #: associated with |ASN.1| type.
282 tagSet = AbstractCharacterString.tagSet.tagImplicitly(
283 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12)
284 )
285 encoding = "utf-8"
286
287 # Optimization for faster codec lookup
288 typeId = AbstractCharacterString.getTypeId()