[esnacc-dev] [RFC] python: Introduce Python library
Aaron Conole
aconole at bytheb.org
Tue Dec 13 21:11:39 UTC 2016
This commit introduces ASN.1 primitive types for ASN.1 Integer,
Enumerated, Octet-String, RelativeOID, OID, Bit-String, and the various
collected string types.
Additionally, a tiny buffer system is added.
Signed-off-by: Aaron Conole <aconole at bytheb.org>
---
This is an early feedback release. There is still quite a bit to do, but it
should be usable for decoding integers, enums, and octet strings.
py-lib/.gitignore | 1 +
py-lib/esnacc/__init__.py | 7 ++
py-lib/esnacc/asn_base.py | 103 +++++++++++++++++++
py-lib/esnacc/asn_buffer.py | 119 ++++++++++++++++++++++
py-lib/esnacc/asn_ints.py | 188 +++++++++++++++++++++++++++++++++++
py-lib/esnacc/asn_octs.py | 93 +++++++++++++++++
py-lib/esnacctests/__init__.py | 7 ++
py-lib/esnacctests/asn_ints_test.py | 192 ++++++++++++++++++++++++++++++++++++
8 files changed, 710 insertions(+)
create mode 100644 py-lib/.gitignore
create mode 100644 py-lib/esnacc/__init__.py
create mode 100644 py-lib/esnacc/asn_base.py
create mode 100644 py-lib/esnacc/asn_buffer.py
create mode 100644 py-lib/esnacc/asn_ints.py
create mode 100644 py-lib/esnacc/asn_octs.py
create mode 100644 py-lib/esnacctests/__init__.py
create mode 100755 py-lib/esnacctests/asn_ints_test.py
diff --git a/py-lib/.gitignore b/py-lib/.gitignore
new file mode 100644
index 0000000..0d20b64
--- /dev/null
+++ b/py-lib/.gitignore
@@ -0,0 +1 @@
+*.pyc
diff --git a/py-lib/esnacc/__init__.py b/py-lib/esnacc/__init__.py
new file mode 100644
index 0000000..c274353
--- /dev/null
+++ b/py-lib/esnacc/__init__.py
@@ -0,0 +1,7 @@
+# Copyright (C) 2016, Aaron Conole <aconole at bytheb.org>
+#
+# Licensed under the terms of the GNU General Public License
+# agreement (version 2 or greater). Alternately, may be licensed
+# under the terms of the ESNACC Public License.
+#
+# This file intentionally blank...
diff --git a/py-lib/esnacc/asn_base.py b/py-lib/esnacc/asn_base.py
new file mode 100644
index 0000000..148a438
--- /dev/null
+++ b/py-lib/esnacc/asn_base.py
@@ -0,0 +1,103 @@
+# Copyright (C) 2016, Aaron Conole <aconole at bytheb.org>
+#
+# Licensed under the terms of the GNU General Public License
+# agreement (version 2 or greater). Alternately, may be licensed
+# under the terms of the ESNACC Public License.
+#
+# ASN.1 Base type for eSNACC
+
+from asn_buffer import BDecDefLen
+from asn_buffer import BEncDefLen
+
+
+class Constraint(object):
+ def __init__(self):
+ pass
+
+ def withinConstraint(self, value):
+ raise NotImplementedError
+
+
+class BERConsts(object):
+ BER_ANY_CLASS = -2
+ BER_NULL_CLASS = -1
+ BER_UNIVERSAL_CLASS = 0
+ BER_APPLICATION_CLASS = 1
+ BER_CONTEXTUAL_CLASS = 2
+ BER_PRIVATE_CLASS = 3
+
+ BER_ANY_FORM = -2
+ BER_NULL_FORM = -1
+ BER_PRIMITIVE_FORM = 0
+ BER_CONSTRUCTED_FORM = 1
+
+
+class AsnBase(object):
+ def __init__(self):
+ pass
+
+ def typename(self):
+ raise NotImplementedError
+
+ def passesAllConstraints(self, constraints):
+ return True
+
+ def addConstraint(self, constraint):
+ if not self.constraints:
+ self.constraints = []
+ self.constraints.append(constraint)
+
+ def BEncContent(self, asnbuf):
+ raise NotImplementedError
+
+ def BDecContent(self, asnbuf, contentlen):
+ raise NotImplementedError
+
+ def BEnc(self, asnbuf):
+ if self.constraints is not None and \
+ not self.passesAllConstraints(self.constraints):
+ raise ValueError("Not all constraints passed")
+
+ asnlen = self.BEncContent(asnbuf)
+ asnlen += BEncDefLen(asnbuf, asnlen)
+ TAG_CODE = BERConsts.BER_UNIVERSAL_CLASS & 0xff | \
+ BERConsts.BER_PRIMITIVE_FORM & 0xff | \
+ self.BER_TAG & 0xff
+ asnlen += asnbuf.PutBufReverse(chr(TAG_CODE))
+ return asnlen
+
+ def BDec(self, asnbuf, asnlen):
+ bufTag = ord(asnbuf.Buffer()[0])
+
+ PRIM_TAG = BERConsts.BER_UNIVERSAL_CLASS & 0xff | \
+ BERConsts.BER_PRIMITIVE_FORM & 0xff | \
+ self.BER_TAG & 0xff
+ CONS_TAG = BERConsts.BER_UNIVERSAL_CLASS & 0xff | \
+ BERConsts.BER_CONSTRUCTED_FORM & 0xff | \
+ self.BER_TAG & 0xff
+
+ if bufTag != PRIM_TAG and bufTag != CONS_TAG:
+ raise IOError("Invalid bytes 0x%02x expected [0x%02x|0x%02x]" %
+ (ord(bufTag), ord(PRIM_TAG), ord(CONS_TAG)))
+
+ asnbuf.swallow(1)
+ asnlen += 1
+ tag_total_len, totalBytesLength = BDecDefLen(asnbuf)
+ asnlen += tag_total_len
+ asnlen += totalBytesLength
+ self.BDecContent(asnbuf, totalBytesLength)
+ return asnlen
+
+ def BEncPdu(self, asnbuf, asnlen):
+ try:
+ asnlen = self.BEnc(asnbuf)
+ except Exception:
+ return False
+ return True, asnlen
+
+ def BDecPdu(self, asnbuf, asnlen):
+ try:
+ asnlen = self.BDec(asnbuf, asnlen)
+ except Exception:
+ return False
+ return True, asnlen
diff --git a/py-lib/esnacc/asn_buffer.py b/py-lib/esnacc/asn_buffer.py
new file mode 100644
index 0000000..c9a368c
--- /dev/null
+++ b/py-lib/esnacc/asn_buffer.py
@@ -0,0 +1,119 @@
+# Copyright (C) 2016, Aaron Conole <aconole at bytheb.org>
+#
+# Licensed under the terms of the GNU General Public License
+# agreement (version 2 or greater). Alternately, may be licensed
+# under the terms of the ESNACC Public License.
+#
+# ASN.1 Buffer library for eSNACC
+
+
+def ints2octs(listOfInts):
+ return [chr(int(x)) for x in listOfInts]
+
+
+def BEncDefLen(asnbuf, length):
+ if length < 128:
+ asnbuf.PutBufReverse(chr(length & 0xff))
+ return 1
+ elif length < 256:
+ asnbuf.PutBufReverse(chr(length & 0xff))
+ asnbuf.PutBufReverse(chr(0x81))
+ return 2
+ elif length < 65536:
+ asnbuf.PutBufReverse(chr(length & 0xff))
+ asnbuf.PutBufReverse(chr((length & 0xff00) >> 8))
+ asnbuf.PutBufReverse(chr(0x82))
+ return 3
+ elif length < 16777126:
+ asnbuf.PutBufReverse(chr(length & 0xff))
+ asnbuf.PutBufReverse(chr((length & 0xff00) >> 8))
+ asnbuf.PutBufReverse(chr((length & 0xff0000) >> 16))
+ asnbuf.PutBufReverse(chr(0x83))
+ return 4
+ else:
+ asnbuf.PutBufReverse(chr(length & 0xff))
+ asnbuf.PutBufReverse(chr((length & 0xff00) >> 8))
+ asnbuf.PutBufReverse(chr((length & 0xff0000) >> 16))
+ asnbuf.PutBufReverse(chr((length & 0xff000000) >> 24))
+ asnbuf.PutBufReverse(chr(0x84))
+ return 5
+
+
+def BDecDefLen(asnbuf):
+ lenByte = ord(asnbuf.GetByte())
+ if lenByte < 128:
+ return 1, lenByte
+ elif lenByte == 0x80:
+ raise IOError("INDEFINITE length not supported")
+
+ bytesTotal = lenByte & 0x7f
+ lenByte = 0
+ for b in range(bytesTotal):
+ lenByte = lenByte << 8
+ lenByte += asnbuf.GetByte()
+ return bytesTotal, lenByte
+
+
+class AsnBuf(object):
+
+ def __init__(self, bufbytes=None):
+ if bufbytes is None:
+ self.buf = []
+ else:
+ self.buf = bufbytes
+
+ def __len__(self):
+ return len(self.buf)
+
+ def PutBufReverse(self, listOf):
+ length = 0
+ if isinstance(listOf, list):
+ for x in reversed(listOf):
+ length += self.PutBufReverse(x)
+ else:
+ self.buf.insert(0, listOf)
+ length = 1
+ return length
+
+ def PutBufIntsReverse(self, listOfInts):
+ return self.PutBufReverse(ints2octs(listOfInts))
+
+ def PutBuf(self, listOf):
+ length = 0
+ if isinstance(listOf, list):
+ for x in listOf:
+ length += self.PutBuf(x)
+ else:
+ self.buf.append(listOf)
+ length = 1
+ return length
+
+ def PutBufInts(self, listOfInts):
+ return self.PutBuf(ints2octs(listOfInts))
+
+ def Buffer(self):
+ return self.buf
+
+ def swallow(self, num):
+ if len(self.buf) < num:
+ raise ValueError("Too many bytes to swallow")
+
+ for x in range(num):
+ del self.buf[0]
+
+ def GetByte(self):
+ ret = self.buf[0]
+ self.swallow(1)
+ return ret
+
+ def GetSeg(self, length):
+ ret = []
+
+ if len(self.buf) < length:
+ raise ValueError("Too many bytes specified")
+
+ for x in range(length):
+ ret.append(self.buf[0])
+ del self.buf[0]
+
+ return ret
diff --git a/py-lib/esnacc/asn_ints.py b/py-lib/esnacc/asn_ints.py
new file mode 100644
index 0000000..85a6b96
--- /dev/null
+++ b/py-lib/esnacc/asn_ints.py
@@ -0,0 +1,188 @@
+# Copyright (C) 2016, Aaron Conole <aconole at bytheb.org>
+#
+# Licensed under the terms of the GNU General Public License
+# agreement (version 2 or greater). Alternately, may be licensed
+# under the terms of the ESNACC Public License.
+#
+# ASN.1 Integer Types for eSNACC
+
+from asn_base import AsnBase
+from asn_base import Constraint
+from asn_buffer import AsnBuf
+
+
+class IntegerConstraint(Constraint):
+ def __init__(self, lowerBound=None, upperBound=None):
+ self.lower = lowerBound
+ self.upper = upperBound
+
+ def withinConstraint(self, value):
+ if self.lower is not None and value is not None and value < self.lower:
+ return False
+ if self.upper is not None and value is not None and value > self.upper:
+ return False
+ return True
+
+
+def isfundamental_int_type(value):
+ if isinstance(value, int) or isinstance(value, float) or \
+ isinstance(value, basestring):
+ return True
+ return False
+
+
+class AsnInt(AsnBase):
+
+ BER_TAG = 0x2
+
+ def __init__(self, value=None):
+ self.constraints = None
+ if value is None:
+ self.intVal = 0
+ elif isfundamental_int_type(value):
+ self.intVal = int(value)
+ elif isinstance(value, AsnInt):
+ self.intVal = value.intVal
+ else:
+ raise ValueError("AsnInt - bad value")
+
+ def __cmp__(self, obj):
+ cmpValA = self.intVal
+ if isinstance(obj, int):
+ cmpValB = obj
+ elif isinstance(obj, AsnInt):
+ cmpValB = obj.intVal
+ elif isinstance(obj, basestring) or isinstance(obj, float):
+ cmpValB = int(obj)
+ else:
+ raise TypeError("Compare with int, or AsnInt")
+ return cmp(cmpValA, cmpValB)
+
+ def value(self, newval=None):
+ if newval is not None:
+ if isinstance(newval, int) or isinstance(newval, float) or \
+ isinstance(newval, basestring):
+ self.intVal = int(newval)
+ elif isinstance(newval, AsnInt):
+ self.intVal = newval.intVal
+ return self.intVal
+
+ def __int__(self):
+ return self.value()
+
+ def __float__(self):
+ return float(self.intVal)
+
+ def __add__(self, obj):
+ if isinstance(obj, AsnInt):
+ return self.intVal + obj.intVal
+ return self.intVal + int(obj)
+
+ def __iadd__(self, obj):
+ if isinstance(obj, AsnInt):
+ self.intVal += obj.intVal
+ else:
+ self.intVal += int(obj)
+ return self
+
+ def __sub__(self, obj):
+ if isinstance(obj, AsnInt):
+ return self.intVal - obj.intVal
+ return self.intVal - int(obj)
+
+ def __isub__(self, obj):
+ if isinstance(obj, AsnInt):
+ self.intVal -= obj.intVal
+ else:
+ self.intVal -= int(obj)
+ return self
+
+ def __mul__(self, obj):
+ if isinstance(obj, AsnInt):
+ return self.intVal * obj.intVal
+ return self.intVal * obj
+
+ def __imul__(self, obj):
+ if isinstance(obj, AsnInt):
+ self.intVal *= obj.intVal
+ else:
+ self.intVal *= obj
+ return self
+
+ def typename(self):
+ return "AsnInt"
+
+ def passesAllConstraints(self, constraints):
+ if constraints is None:
+ return True
+ if isinstance(constraints, IntegerConstraint):
+ return constraints.withinConstraint(self.intVal)
+ elif isinstance(constraints, list):
+ for x in constraints:
+ if not self.passesAllConstraints(x):
+ return False
+ return True
+
+ def BEncContent(self, asnbuf):
+ if not isinstance(asnbuf, AsnBuf):
+ raise ValueError("Buffer must be esnacc.asn_buf.AsnBuf")
+
+ octets = []
+ value = self.intVal
+ while 1:
+ octets.insert(0, value & 0xff)
+ if value == 0 or value == -1:
+ break
+ value = value >> 8
+ if value == 0 and octets[0] & 0x80:
+ octets.insert(0, 0)
+ while len(octets) > 1 and \
+ (octets[0] == 0 and octets[1] & 0x80 == 0 or
+ octets[0] == 0xff and octets[1] & 0x80 != 0):
+ del octets[0]
+
+ asnbuf.PutBufIntsReverse(octets)
+ return len(octets)
+
+ def BDecContent(self, asnbuf, intlen):
+ buf = ord(asnbuf.Buffer()[0])
+ result = 0
+ if buf & 0x80:
+ result = -1
+
+ for x in range(intlen):
+ result <<= 8
+ result |= ord(asnbuf.GetByte())
+ self.intVal = result
+ return intlen
+
+
+class EnumeratedConstraint(Constraint):
+ def __init__(self, listOfEnumerations):
+ self.enums = listOfEnumerations
+
+ def withinConstraint(self, value):
+ if value not in self.enums:
+ return False
+ return True
+
+
+class AsnEnum(AsnInt):
+ BER_TAG = 0xa
+
+ def __init__(self, val=None):
+ self.constraints = None
+ if val is not None:
+ self.intVal = val
+
+ def passesAllConstraints(self, constraints):
+ if constraints is None:
+ return True
+ if isinstance(constraints, IntegerConstraint) \
+ or isinstance(constraints, EnumeratedConstraint):
+ return constraints.withinConstraint(self.intVal)
+ elif isinstance(constraints, list):
+ for x in constraints:
+ if not self.passesAllConstraints(x):
+ return False
+ return True
diff --git a/py-lib/esnacc/asn_octs.py b/py-lib/esnacc/asn_octs.py
new file mode 100644
index 0000000..b3682e7
--- /dev/null
+++ b/py-lib/esnacc/asn_octs.py
@@ -0,0 +1,93 @@
+# Copyright (C) 2016, Aaron Conole <aconole at bytheb.org>
+#
+# Licensed under the terms of the GNU General Public License
+# agreement (version 2 or greater). Alternately, may be licensed
+# under the terms of the ESNACC Public License.
+#
+# ASN.1 Integer Types for eSNACC
+
+from asn_base import AsnBase
+from asn_base import Constraint
+
+
+class CharacterValueConstraint(Constraint):
+ def __init__(self, lowerBound=None, upperBound=None, charList=None):
+ self.lower = lowerBound
+ self.upper = upperBound
+ self.chars = charList
+
+ def withinConstraint(self, value):
+ if isinstance(value, list) or isinstance(value, basestring):
+ for x in value:
+ if self.withinConstraint(x):
+ return False
+ if self.lower is not None and value is not None and \
+ value < self.lower:
+ return False
+ if self.upper is not None and value is not None and \
+ value > self.upper:
+ return False
+ if self.chars is not None and value is not None and \
+ value not in self.chars:
+ return False
+ return True
+
+
+class OctetLengthConstraint(Constraint):
+ def __init__(self, length=None):
+ self.length = length
+
+ def withinConstraint(self, value):
+ if isinstance(value, list) or isinstance(value, basestring):
+ if len(value) <= self.length:
+ return True
+ return False
+
+
+class AsnOcts(AsnBase):
+ BER_TAG = 4
+
+ def __init__(self, octets=None):
+ self.constraints = None
+ self.octs = None
+ if octets is not None:
+ self.setData(octets)
+
+ def __getitem__(self, idx):
+ if self.octs is None or idx > len(self.octs):
+ raise IndexError("Octet value out of range")
+ return self.octs[idx]
+
+ def __contains__(self, a):
+ if self.octs is not None:
+ return a in self.octs
+ return None
+
+ def __len__(self):
+ if self.octs is not None:
+ return len(self.octs)
+ return 0
+
+ def __delitem__(self, idx):
+ if self.octs is not None:
+ del self.octs[idx]
+ raise IndexError("Out of range")
+
+ def octs(self):
+ return self.octs
+
+ def setData(self, octets):
+ if isinstance(octets, list):
+ self.octs = octets
+ elif isinstance(octets, basestring):
+ self.octs = []
+ for x in octets:
+ self.octs.append(chr(ord(x)))
+
+ def BEncContent(self, asnbuf):
+ asnbuf.PutBufReverse(self.octs)
+ return len(self.octs)
+
+ def BDecContent(self, asnbuf, contentlen):
+ self.octs = asnbuf.GetSeg(contentlen)
+ return len(self.octs)
diff --git a/py-lib/esnacctests/__init__.py b/py-lib/esnacctests/__init__.py
new file mode 100644
index 0000000..c274353
--- /dev/null
+++ b/py-lib/esnacctests/__init__.py
@@ -0,0 +1,7 @@
+# Copyright (C) 2016, Aaron Conole <aconole at bytheb.org>
+#
+# Licensed under the terms of the GNU General Public License
+# agreement (version 2 or greater). Alternately, may be licensed
+# under the terms of the ESNACC Public License.
+#
+# This file intentionally blank...
diff --git a/py-lib/esnacctests/asn_ints_test.py b/py-lib/esnacctests/asn_ints_test.py
new file mode 100755
index 0000000..4258940
--- /dev/null
+++ b/py-lib/esnacctests/asn_ints_test.py
@@ -0,0 +1,192 @@
+#!/usr/bin/env python
+# Copyright (C) 2016, Aaron Conole <aconole at bytheb.org>
+#
+# Licensed under the terms of the GNU General Public License
+# agreement (version 2 or greater). Alternately, may be licensed
+# under the terms of the ESNACC Public License.
+#
+# ESNACC ASN.1 integer tests
+
+import unittest
+if __package__ is None:
+ import sys
+ from os import path
+ sys.path.append( path.dirname( path.dirname( path.abspath(__file__) ) ) )
+ from esnacc import asn_ints
+ from esnacc import asn_buffer
+else:
+ from ..esnacc import asn_ints
+ from ..esnacc import asn_buffer
+
+class TestAsnInts(unittest.TestCase):
+ def test_operations_default(self):
+ asninteger = asn_ints.AsnInt(1)
+
+ self.assertTrue(asninteger == 1)
+ self.assertTrue(asninteger > 0)
+ self.assertTrue(asninteger < 2)
+
+ asninteger += 1
+
+ self.assertTrue(asninteger == 2)
+ self.assertTrue((asninteger * 1) == 2)
+ self.assertTrue((asninteger - 1) == 1)
+
+ def test_ber_encoder_simple(self):
+ class testVec(unittest.TestCase):
+ def __init__(self, number, length, byteCodes):
+ self.nm = number
+ self.ln = length
+ self.bc = byteCodes
+
+ def run(self):
+ asninteger = asn_ints.AsnInt(self.nm)
+ asnbuf = asn_buffer.AsnBuf()
+
+ self.assertTrue(asninteger.BEnc(asnbuf) == self.ln)
+ byteCodes = asnbuf.Buffer()
+ self.assertTrue(len(byteCodes) == len(self.bc))
+ for x in range(len(byteCodes)):
+ self.assertTrue(self.bc[x] == byteCodes[x])
+ return True
+
+ tests = []
+ tvn65535codes = [chr(0x2), chr(0x3), chr(0xff), chr(0x0), chr(0x1)]
+ tests.append(testVec(-65535, 5, tvn65535codes))
+
+ tvn10codes = [chr(0x2), chr(0x1), chr(0xf6)]
+ tests.append(testVec(-10, 3, tvn10codes))
+
+ tv0codes = [chr(0x2), chr(0x1), chr(0x0)]
+ tests.append(testVec(0, 3, tv0codes))
+
+ tv1codes = [chr(0x2), chr(0x1), chr(0x1)]
+ tests.append(testVec(1, 3, tv1codes))
+
+ tv2codes = [chr(0x2), chr(0x2), chr(0x3f), chr(0xc3)]
+ tests.append(testVec(16323, 4, tv2codes))
+
+ tv3codes = [chr(0x2), chr(02), chr(0x7f), chr(0xff)]
+ tests.append(testVec(32767, 4, tv3codes))
+
+ tv4codes = [chr(0x2), chr(0x3), chr(0x00), chr(0x80), chr(0x00)]
+ tests.append(testVec(32768, 5, tv4codes))
+
+ tv5codes = [chr(0x2), chr(0x3), chr(0x20), chr(0x00), chr(0x00)]
+ tests.append(testVec(2097152, 5, tv5codes))
+
+ tv6codes = [chr(0x2), chr(0x4), chr(0x1), chr(0x0), chr(0x0), chr(0x0)]
+ tests.append(testVec(16777216, 6, tv6codes))
+
+ for x in tests:
+ self.assertTrue(x.run())
+
+ def test_ber_decoder_simple(self):
+ class testVec(unittest.TestCase):
+ def __init__(self, number, length, byteCodes):
+ self.nm = number
+ self.ln = length
+ self.bc = byteCodes
+
+ def run(self):
+ asnbuf = asn_buffer.AsnBuf(self.bc)
+ asninteger = asn_ints.AsnInt()
+ self.assertTrue(asninteger.BDec(asnbuf, 0) == self.ln)
+ self.assertTrue(self.nm == int(asninteger))
+ return True
+
+ tests = []
+ tvn65535codes = [chr(0x2), chr(0x3), chr(0xff), chr(0x0), chr(0x1)]
+ tests.append(testVec(-65535, 5, tvn65535codes))
+
+ tvn10codes = [chr(0x2), chr(0x1), chr(0xf6)]
+ tests.append(testVec(-10, 3, tvn10codes))
+
+ tv0codes = [chr(0x2), chr(0x1), chr(0x0)]
+ tests.append(testVec(0, 3, tv0codes))
+
+ tv1codes = [chr(0x2), chr(0x1), chr(0x1)]
+ tests.append(testVec(1, 3, tv1codes))
+
+ tv2codes = [chr(0x2), chr(0x2), chr(0x3f), chr(0xc3)]
+ tests.append(testVec(16323, 4, tv2codes))
+
+ tv3codes = [chr(0x2), chr(02), chr(0x7f), chr(0xff)]
+ tests.append(testVec(32767, 4, tv3codes))
+
+ tv4codes = [chr(0x2), chr(0x3), chr(0x00), chr(0x80), chr(0x00)]
+ tests.append(testVec(32768, 5, tv4codes))
+
+ tv5codes = [chr(0x2), chr(0x3), chr(0x20), chr(0x00), chr(0x00)]
+ tests.append(testVec(2097152, 5, tv5codes))
+
+ tv6codes = [chr(0x2), chr(0x4), chr(0x1), chr(0x0), chr(0x0), chr(0x0)]
+ tests.append(testVec(16777216, 6, tv6codes))
+
+ for x in tests:
+ self.assertTrue(x.run())
+
+
+ def test_constraints(self):
+ class testVec(unittest.TestCase):
+ def __init__(self, number):
+ self.nm = number
+
+ def run(self):
+ cnstraint_good = asn_ints.IntegerConstraint(self.nm-1, self.nm+1)
+ asninteger = asn_ints.AsnInt(self.nm)
+ asninteger.addConstraint(cnstraint_good)
+
+ buf = asn_buffer.AsnBuf()
+ self.assertTrue(asninteger.BEnc(buf) != 0)
+
+ cnstraint_bad = asn_ints.IntegerConstraint(self.nm+1, self.nm+2)
+ asninteger.addConstraint(cnstraint_bad)
+ with self.assertRaises(ValueError):
+ asninteger.BEnc(buf)
+ return True
+
+ tests = []
+ tests.append(testVec(-65535))
+ tests.append(testVec(-10))
+ tests.append(testVec(0))
+ tests.append(testVec(1))
+ tests.append(testVec(16323))
+ tests.append(testVec(32767))
+ tests.append(testVec(32768))
+ tests.append(testVec(2097152))
+ tests.append(testVec(16777216))
+
+ for x in tests:
+ self.assertTrue(x.run())
+
+class TestAsnEnums(unittest.TestCase):
+ def test_enumeration_encoding(self):
+ class testVec(unittest.TestCase):
+ def __init__(self, number, length, byteCodes):
+ self.nm = number
+ self.ln = length
+ self.bc = byteCodes
+
+ def run(self):
+ asnenum = asn_ints.AsnEnum(self.nm)
+ asnbuf = asn_buffer.AsnBuf()
+
+ self.assertTrue(asnenum.BEnc(asnbuf) == self.ln)
+ byteCodes = asnbuf.Buffer()
+ self.assertTrue(len(byteCodes) == len(self.bc))
+ for x in range(len(byteCodes)):
+ self.assertTrue(self.bc[x] == byteCodes[x])
+ return True
+
+ tests = []
+ tv0codes = [chr(0xa), chr(0x1), chr(0x0)]
+ tests.append(testVec(0, 3, tv0codes))
+
+ for x in tests:
+ self.assertTrue(x.run())
+
+
+if __name__ == '__main__':
+
+ unittest.main()
--
2.7.4
More information about the dev
mailing list