summaryrefslogtreecommitdiff
path: root/pyasn1/codec/cer/encoder.py
diff options
context:
space:
mode:
authorIlya Etingof <etingof@gmail.com>2017-07-27 15:19:12 +0200
committerIlya Etingof <etingof@gmail.com>2017-07-27 15:19:12 +0200
commit7c5db3287f2a99e830066279b1973b61eb11453e (patch)
tree022f8942cbbf8342192644767903508864e4244a /pyasn1/codec/cer/encoder.py
parentf8b20f2b809f22ab9d55a32d5f6422251c9ab731 (diff)
downloadpyasn1-git-7c5db3287f2a99e830066279b1973b61eb11453e.tar.gz
fixed CER/DER codec for GeneralizedTime/UTCTime
Diffstat (limited to 'pyasn1/codec/cer/encoder.py')
-rw-r--r--pyasn1/codec/cer/encoder.py61
1 files changed, 33 insertions, 28 deletions
diff --git a/pyasn1/codec/cer/encoder.py b/pyasn1/codec/cer/encoder.py
index 17728c6..021fd22 100644
--- a/pyasn1/codec/cer/encoder.py
+++ b/pyasn1/codec/cer/encoder.py
@@ -7,7 +7,7 @@
from pyasn1.type import univ
from pyasn1.type import useful
from pyasn1.codec.ber import encoder
-from pyasn1.compat.octets import int2oct, str2octs, null
+from pyasn1.compat.octets import str2octs, null
from pyasn1 import error
__all__ = ['encode']
@@ -44,46 +44,51 @@ class RealEncoder(encoder.RealEncoder):
# specialized GeneralStringEncoder here
-class GeneralizedTimeEncoder(OctetStringEncoder):
- zchar = str2octs('Z')
- pluschar = str2octs('+')
- minuschar = str2octs('-')
- zero = str2octs('0')
+class TimeEncoderMixIn(object):
+ zchar, = str2octs('Z')
+ pluschar, = str2octs('+')
+ minuschar, = str2octs('-')
+ commachar, = str2octs(',')
+ minLength = 12
+ maxLength = 19
def encodeValue(self, encodeFun, client, defMode, maxChunkSize):
+ # Encoding constraints:
+ # - minutes are mandatory, seconds are optional
+ # - subseconds must NOT be zero
+ # - no hanging fraction dot
+ # - time in UTC (Z)
+ # - only dot is allowed for fractions
+
octets = client.asOctets()
- # This breaks too many existing data items
- # if '.' not in octets:
- # raise error.PyAsn1Error('Format must include fraction of second: %r' % octets)
- if len(octets) < 15:
- raise error.PyAsn1Error('Bad UTC time length: %r' % octets)
+
+ if not self.minLength < len(octets) < self.maxLength:
+ raise error.PyAsn1Error('Length constraint violated: %r' % client)
+
if self.pluschar in octets or self.minuschar in octets:
raise error.PyAsn1Error('Must be UTC time: %r' % octets)
- if octets[-1] != self.zchar[0]:
- raise error.PyAsn1Error('Missing timezone specifier: %r' % octets)
- return encoder.OctetStringEncoder.encodeValue(
- self, encodeFun, client, defMode, 1000
- )
+ if octets[-1] != self.zchar:
+ raise error.PyAsn1Error('Missing "Z" time zone specifier: %r' % octets)
-class UTCTimeEncoder(encoder.OctetStringEncoder):
- zchar = str2octs('Z')
- pluschar = str2octs('+')
- minuschar = str2octs('-')
+ if self.commachar in octets:
+ raise error.PyAsn1Error('Comma in fractions disallowed: %r' % client)
- def encodeValue(self, encodeFun, client, defMode, maxChunkSize):
- octets = client.asOctets()
- if self.pluschar in octets or self.minuschar in octets:
- raise error.PyAsn1Error('Must be UTC time: %r' % octets)
- if octets and octets[-1] != self.zchar[0]:
- client = client.clone(octets + self.zchar)
- if len(client) != 13:
- raise error.PyAsn1Error('Bad UTC time length: %r' % client)
return encoder.OctetStringEncoder.encodeValue(
self, encodeFun, client, defMode, 1000
)
+class GeneralizedTimeEncoder(TimeEncoderMixIn, OctetStringEncoder):
+ minLength = 12
+ maxLength = 19
+
+
+class UTCTimeEncoder(TimeEncoderMixIn, encoder.OctetStringEncoder):
+ minLength = 10
+ maxLength = 14
+
+
class SetOfEncoder(encoder.SequenceOfEncoder):
@staticmethod
def _sortComponents(components):