OLD | NEW |
(Empty) | |
| 1 # CER encoder |
| 2 from pyasn1.type import univ |
| 3 from pyasn1.type import useful |
| 4 from pyasn1.codec.ber import encoder |
| 5 from pyasn1.compat.octets import int2oct, str2octs, null |
| 6 from pyasn1 import error |
| 7 |
| 8 class BooleanEncoder(encoder.IntegerEncoder): |
| 9 def encodeValue(self, encodeFun, client, defMode, maxChunkSize): |
| 10 if client == 0: |
| 11 substrate = int2oct(0) |
| 12 else: |
| 13 substrate = int2oct(255) |
| 14 return substrate, 0 |
| 15 |
| 16 class BitStringEncoder(encoder.BitStringEncoder): |
| 17 def encodeValue(self, encodeFun, client, defMode, maxChunkSize): |
| 18 return encoder.BitStringEncoder.encodeValue( |
| 19 self, encodeFun, client, defMode, 1000 |
| 20 ) |
| 21 |
| 22 class OctetStringEncoder(encoder.OctetStringEncoder): |
| 23 def encodeValue(self, encodeFun, client, defMode, maxChunkSize): |
| 24 return encoder.OctetStringEncoder.encodeValue( |
| 25 self, encodeFun, client, defMode, 1000 |
| 26 ) |
| 27 |
| 28 class RealEncoder(encoder.RealEncoder): |
| 29 def _chooseEncBase(self, value): |
| 30 m, b, e = value |
| 31 return self._dropFloatingPoint(m, b, e) |
| 32 |
| 33 # specialized GeneralStringEncoder here |
| 34 |
| 35 class GeneralizedTimeEncoder(OctetStringEncoder): |
| 36 zchar = str2octs('Z') |
| 37 pluschar = str2octs('+') |
| 38 minuschar = str2octs('-') |
| 39 zero = str2octs('0') |
| 40 def encodeValue(self, encodeFun, client, defMode, maxChunkSize): |
| 41 octets = client.asOctets() |
| 42 # This breaks too many existing data items |
| 43 # if '.' not in octets: |
| 44 # raise error.PyAsn1Error('Format must include fraction of second: %r
' % octets) |
| 45 if len(octets) < 15: |
| 46 raise error.PyAsn1Error('Bad UTC time length: %r' % octets) |
| 47 if self.pluschar in octets or self.minuschar in octets: |
| 48 raise error.PyAsn1Error('Must be UTC time: %r' % octets) |
| 49 if octets[-1] != self.zchar[0]: |
| 50 raise error.PyAsn1Error('Missing timezone specifier: %r' % octets) |
| 51 return encoder.OctetStringEncoder.encodeValue( |
| 52 self, encodeFun, client, defMode, 1000 |
| 53 ) |
| 54 |
| 55 class UTCTimeEncoder(encoder.OctetStringEncoder): |
| 56 zchar = str2octs('Z') |
| 57 pluschar = str2octs('+') |
| 58 minuschar = str2octs('-') |
| 59 def encodeValue(self, encodeFun, client, defMode, maxChunkSize): |
| 60 octets = client.asOctets() |
| 61 if self.pluschar in octets or self.minuschar in octets: |
| 62 raise error.PyAsn1Error('Must be UTC time: %r' % octets) |
| 63 if octets and octets[-1] != self.zchar[0]: |
| 64 client = client.clone(octets + self.zchar) |
| 65 if len(client) != 13: |
| 66 raise error.PyAsn1Error('Bad UTC time length: %r' % client) |
| 67 return encoder.OctetStringEncoder.encodeValue( |
| 68 self, encodeFun, client, defMode, 1000 |
| 69 ) |
| 70 |
| 71 class SetOfEncoder(encoder.SequenceOfEncoder): |
| 72 def encodeValue(self, encodeFun, client, defMode, maxChunkSize): |
| 73 if isinstance(client, univ.SequenceAndSetBase): |
| 74 client.setDefaultComponents() |
| 75 client.verifySizeSpec() |
| 76 substrate = null; idx = len(client) |
| 77 # This is certainly a hack but how else do I distinguish SetOf |
| 78 # from Set if they have the same tags&constraints? |
| 79 if isinstance(client, univ.SequenceAndSetBase): |
| 80 # Set |
| 81 comps = [] |
| 82 while idx > 0: |
| 83 idx = idx - 1 |
| 84 if client[idx] is None: # Optional component |
| 85 continue |
| 86 if client.getDefaultComponentByPosition(idx) == client[idx]: |
| 87 continue |
| 88 comps.append(client[idx]) |
| 89 comps.sort(key=lambda x: isinstance(x, univ.Choice) and \ |
| 90 x.getMinTagSet() or x.getTagSet()) |
| 91 for c in comps: |
| 92 substrate += encodeFun(c, defMode, maxChunkSize) |
| 93 else: |
| 94 # SetOf |
| 95 compSubs = [] |
| 96 while idx > 0: |
| 97 idx = idx - 1 |
| 98 compSubs.append( |
| 99 encodeFun(client[idx], defMode, maxChunkSize) |
| 100 ) |
| 101 compSubs.sort() # perhaps padding's not needed |
| 102 substrate = null |
| 103 for compSub in compSubs: |
| 104 substrate += compSub |
| 105 return substrate, 1 |
| 106 |
| 107 tagMap = encoder.tagMap.copy() |
| 108 tagMap.update({ |
| 109 univ.Boolean.tagSet: BooleanEncoder(), |
| 110 univ.BitString.tagSet: BitStringEncoder(), |
| 111 univ.OctetString.tagSet: OctetStringEncoder(), |
| 112 univ.Real.tagSet: RealEncoder(), |
| 113 useful.GeneralizedTime.tagSet: GeneralizedTimeEncoder(), |
| 114 useful.UTCTime.tagSet: UTCTimeEncoder(), |
| 115 univ.SetOf().tagSet: SetOfEncoder() # conflcts with Set |
| 116 }) |
| 117 |
| 118 typeMap = encoder.typeMap.copy() |
| 119 typeMap.update({ |
| 120 univ.Set.typeId: SetOfEncoder(), |
| 121 univ.SetOf.typeId: SetOfEncoder() |
| 122 }) |
| 123 |
| 124 class Encoder(encoder.Encoder): |
| 125 def __call__(self, client, defMode=False, maxChunkSize=0): |
| 126 return encoder.Encoder.__call__(self, client, defMode, maxChunkSize) |
| 127 |
| 128 encode = Encoder(tagMap, typeMap) |
| 129 |
| 130 # EncoderFactory queries class instance and builds a map of tags -> encoders |
OLD | NEW |