diff options
author | Ilya Etingof <etingof@gmail.com> | 2017-07-27 15:19:12 +0200 |
---|---|---|
committer | Ilya Etingof <etingof@gmail.com> | 2017-07-27 15:19:12 +0200 |
commit | 7c5db3287f2a99e830066279b1973b61eb11453e (patch) | |
tree | 022f8942cbbf8342192644767903508864e4244a /pyasn1/codec/cer/encoder.py | |
parent | f8b20f2b809f22ab9d55a32d5f6422251c9ab731 (diff) | |
download | pyasn1-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.py | 61 |
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): |