Index: third_party/google-endpoints/pyasn1/codec/cer/encoder.py |
diff --git a/third_party/google-endpoints/pyasn1/codec/cer/encoder.py b/third_party/google-endpoints/pyasn1/codec/cer/encoder.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..61ce8a1507c209ec14e4d4400d284ca5a54c3889 |
--- /dev/null |
+++ b/third_party/google-endpoints/pyasn1/codec/cer/encoder.py |
@@ -0,0 +1,130 @@ |
+# CER encoder |
+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 import error |
+ |
+class BooleanEncoder(encoder.IntegerEncoder): |
+ def encodeValue(self, encodeFun, client, defMode, maxChunkSize): |
+ if client == 0: |
+ substrate = int2oct(0) |
+ else: |
+ substrate = int2oct(255) |
+ return substrate, 0 |
+ |
+class BitStringEncoder(encoder.BitStringEncoder): |
+ def encodeValue(self, encodeFun, client, defMode, maxChunkSize): |
+ return encoder.BitStringEncoder.encodeValue( |
+ self, encodeFun, client, defMode, 1000 |
+ ) |
+ |
+class OctetStringEncoder(encoder.OctetStringEncoder): |
+ def encodeValue(self, encodeFun, client, defMode, maxChunkSize): |
+ return encoder.OctetStringEncoder.encodeValue( |
+ self, encodeFun, client, defMode, 1000 |
+ ) |
+ |
+class RealEncoder(encoder.RealEncoder): |
+ def _chooseEncBase(self, value): |
+ m, b, e = value |
+ return self._dropFloatingPoint(m, b, e) |
+ |
+# specialized GeneralStringEncoder here |
+ |
+class GeneralizedTimeEncoder(OctetStringEncoder): |
+ zchar = str2octs('Z') |
+ pluschar = str2octs('+') |
+ minuschar = str2octs('-') |
+ zero = str2octs('0') |
+ def encodeValue(self, encodeFun, client, defMode, maxChunkSize): |
+ 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 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 |
+ ) |
+ |
+class UTCTimeEncoder(encoder.OctetStringEncoder): |
+ zchar = str2octs('Z') |
+ pluschar = str2octs('+') |
+ minuschar = str2octs('-') |
+ 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 SetOfEncoder(encoder.SequenceOfEncoder): |
+ def encodeValue(self, encodeFun, client, defMode, maxChunkSize): |
+ if isinstance(client, univ.SequenceAndSetBase): |
+ client.setDefaultComponents() |
+ client.verifySizeSpec() |
+ substrate = null; idx = len(client) |
+ # This is certainly a hack but how else do I distinguish SetOf |
+ # from Set if they have the same tags&constraints? |
+ if isinstance(client, univ.SequenceAndSetBase): |
+ # Set |
+ comps = [] |
+ while idx > 0: |
+ idx = idx - 1 |
+ if client[idx] is None: # Optional component |
+ continue |
+ if client.getDefaultComponentByPosition(idx) == client[idx]: |
+ continue |
+ comps.append(client[idx]) |
+ comps.sort(key=lambda x: isinstance(x, univ.Choice) and \ |
+ x.getMinTagSet() or x.getTagSet()) |
+ for c in comps: |
+ substrate += encodeFun(c, defMode, maxChunkSize) |
+ else: |
+ # SetOf |
+ compSubs = [] |
+ while idx > 0: |
+ idx = idx - 1 |
+ compSubs.append( |
+ encodeFun(client[idx], defMode, maxChunkSize) |
+ ) |
+ compSubs.sort() # perhaps padding's not needed |
+ substrate = null |
+ for compSub in compSubs: |
+ substrate += compSub |
+ return substrate, 1 |
+ |
+tagMap = encoder.tagMap.copy() |
+tagMap.update({ |
+ univ.Boolean.tagSet: BooleanEncoder(), |
+ univ.BitString.tagSet: BitStringEncoder(), |
+ univ.OctetString.tagSet: OctetStringEncoder(), |
+ univ.Real.tagSet: RealEncoder(), |
+ useful.GeneralizedTime.tagSet: GeneralizedTimeEncoder(), |
+ useful.UTCTime.tagSet: UTCTimeEncoder(), |
+ univ.SetOf().tagSet: SetOfEncoder() # conflcts with Set |
+}) |
+ |
+typeMap = encoder.typeMap.copy() |
+typeMap.update({ |
+ univ.Set.typeId: SetOfEncoder(), |
+ univ.SetOf.typeId: SetOfEncoder() |
+}) |
+ |
+class Encoder(encoder.Encoder): |
+ def __call__(self, client, defMode=False, maxChunkSize=0): |
+ return encoder.Encoder.__call__(self, client, defMode, maxChunkSize) |
+ |
+encode = Encoder(tagMap, typeMap) |
+ |
+# EncoderFactory queries class instance and builds a map of tags -> encoders |