1 # CER encoder 2 from pyasn1.type import univ 3 from pyasn1.codec.ber import encoder 4 from pyasn1.compat.octets import int2oct, null 5 6 class BooleanEncoder(encoder.IntegerEncoder): 7 def encodeValue(self, encodeFun, client, defMode, maxChunkSize): 8 if client == 0: 9 substrate = int2oct(0) 10 else: 11 substrate = int2oct(255) 12 return substrate, 0 13 14 class BitStringEncoder(encoder.BitStringEncoder): 15 def encodeValue(self, encodeFun, client, defMode, maxChunkSize): 16 return encoder.BitStringEncoder.encodeValue( 17 self, encodeFun, client, defMode, 1000 18 ) 19 20 class OctetStringEncoder(encoder.OctetStringEncoder): 21 def encodeValue(self, encodeFun, client, defMode, maxChunkSize): 22 return encoder.OctetStringEncoder.encodeValue( 23 self, encodeFun, client, defMode, 1000 24 ) 25 26 # specialized RealEncoder here 27 # specialized GeneralStringEncoder here 28 # specialized GeneralizedTimeEncoder here 29 # specialized UTCTimeEncoder here 30 31 class SetOfEncoder(encoder.SequenceOfEncoder): 32 def encodeValue(self, encodeFun, client, defMode, maxChunkSize): 33 if isinstance(client, univ.SequenceAndSetBase): 34 client.setDefaultComponents() 35 client.verifySizeSpec() 36 substrate = null; idx = len(client) 37 # This is certainly a hack but how else do I distinguish SetOf 38 # from Set if they have the same tags&constraints? 39 if isinstance(client, univ.SequenceAndSetBase): 40 # Set 41 comps = [] 42 while idx > 0: 43 idx = idx - 1 44 if client[idx] is None: # Optional component 45 continue 46 if client.getDefaultComponentByPosition(idx) == client[idx]: 47 continue 48 comps.append(client[idx]) 49 comps.sort(key=lambda x: isinstance(x, univ.Choice) and \ 50 x.getMinTagSet() or x.getTagSet()) 51 for c in comps: 52 substrate += encodeFun(c, defMode, maxChunkSize) 53 else: 54 # SetOf 55 compSubs = [] 56 while idx > 0: 57 idx = idx - 1 58 compSubs.append( 59 encodeFun(client[idx], defMode, maxChunkSize) 60 ) 61 compSubs.sort() # perhaps padding's not needed 62 substrate = null 63 for compSub in compSubs: 64 substrate += compSub 65 return substrate, 1 66 67 tagMap = encoder.tagMap.copy() 68 tagMap.update({ 69 univ.Boolean.tagSet: BooleanEncoder(), 70 univ.BitString.tagSet: BitStringEncoder(), 71 univ.OctetString.tagSet: OctetStringEncoder(), 72 univ.SetOf().tagSet: SetOfEncoder() # conflcts with Set 73 }) 74 75 typeMap = encoder.typeMap.copy() 76 typeMap.update({ 77 univ.Set.typeId: SetOfEncoder(), 78 univ.SetOf.typeId: SetOfEncoder() 79 }) 80 81 class Encoder(encoder.Encoder): 82 def __call__(self, client, defMode=0, maxChunkSize=0): 83 return encoder.Encoder.__call__(self, client, defMode, maxChunkSize) 84 85 encode = Encoder(tagMap, typeMap) 86 87 # EncoderFactory queries class instance and builds a map of tags -> encoders 88