from datetime import datetime
from math import ceil
from os import environ
+from string import ascii_letters
from string import digits
from six import add_metaclass
# Errors
########################################################################
-class DecodeError(Exception):
+class ASN1Error(ValueError):
+ pass
+
+class DecodeError(ASN1Error):
def __init__(self, msg="", klass=None, decode_path=(), offset=0):
"""
:param str msg: reason of decode failing
pass
-class ObjUnknown(ValueError):
+class ObjUnknown(ASN1Error):
def __init__(self, name):
super(ObjUnknown, self).__init__()
self.name = name
return "%s(%s)" % (self.__class__.__name__, self)
-class ObjNotReady(ValueError):
+class ObjNotReady(ASN1Error):
def __init__(self, name):
super(ObjNotReady, self).__init__()
self.name = name
return "%s(%s)" % (self.__class__.__name__, self)
-class InvalidValueType(ValueError):
+class InvalidValueType(ASN1Error):
def __init__(self, expected_types):
super(InvalidValueType, self).__init__()
self.expected_types = expected_types
return "%s(%s)" % (self.__class__.__name__, self)
-class BoundsError(ValueError):
+class BoundsError(ASN1Error):
def __init__(self, bound_min, value, bound_max):
super(BoundsError, self).__init__()
self.bound_min = bound_min
class NumericString(CommonString):
"""Numeric string
- Its value is properly sanitized: only ASCII digits can be stored.
+ Its value is properly sanitized: only ASCII digits with spaces can
+ be stored.
"""
__slots__ = ()
tag_default = tag_encode(18)
encoding = "ascii"
asn1_type_name = "NumericString"
- allowable_chars = set(digits.encode("ascii"))
+ allowable_chars = set(digits.encode("ascii") + b" ")
def _value_sanitize(self, value):
value = super(NumericString, self)._value_sanitize(value)
class PrintableString(CommonString):
+ """Printable string
+
+ Its value is properly sanitized: see X.680 41.4 table 10.
+ """
__slots__ = ()
tag_default = tag_encode(19)
encoding = "ascii"
asn1_type_name = "PrintableString"
+ allowable_chars = set((ascii_letters + digits + " '()+,-./:=?").encode("ascii"))
+
+ def _value_sanitize(self, value):
+ value = super(PrintableString, self)._value_sanitize(value)
+ if not set(value) <= self.allowable_chars:
+ raise DecodeError("non-printable value")
+ return value
class TeletexString(CommonString):