# -*- coding: utf-8 -*- # # SelfTest/Util/test_asn.py: Self-test for the Crypto.Util.asn1 module # # =================================================================== # The contents of this file are dedicated to the public domain. To # the extent that dedication to the public domain is not available, # everyone is granted a worldwide, perpetual, royalty-free, # non-exclusive license to exercise all rights associated with the # contents of this file for any purpose whatsoever. # No rights are reserved. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. # =================================================================== """Self-tests for Crypto.Util.asn1""" __revision__ = "$Id$" import unittest import sys from Crypto.Util.py3compat import * from Crypto.Util.asn1 import DerSequence, DerObject class DerObjectTests(unittest.TestCase): def testObjEncode1(self): # No payload der = DerObject(b('\x33')) self.assertEquals(der.encode(), b('\x33\x00')) # Small payload der.payload = b('\x45') self.assertEquals(der.encode(), b('\x33\x01\x45')) # Invariant self.assertEquals(der.encode(), b('\x33\x01\x45')) # Initialize with numerical tag der = DerObject(b(0x33)) der.payload = b('\x45') self.assertEquals(der.encode(), b('\x33\x01\x45')) def testObjEncode2(self): # Known types der = DerObject('SEQUENCE') self.assertEquals(der.encode(), b('\x30\x00')) der = DerObject('BIT STRING') self.assertEquals(der.encode(), b('\x03\x00')) def testObjEncode3(self): # Long payload der = DerObject(b('\x34')) der.payload = b("0")*128 self.assertEquals(der.encode(), b('\x34\x81\x80' + "0"*128)) def testObjDecode1(self): # Decode short payload der = DerObject() der.decode(b('\x20\x02\x01\x02')) self.assertEquals(der.payload, b("\x01\x02")) self.assertEquals(der.typeTag, 0x20) def testObjDecode2(self): # Decode short payload der = DerObject() der.decode(b('\x22\x81\x80' + "1"*128)) self.assertEquals(der.payload, b("1")*128) self.assertEquals(der.typeTag, 0x22) class DerSequenceTests(unittest.TestCase): def testEncode1(self): # Empty sequence der = DerSequence() self.assertEquals(der.encode(), b('0\x00')) self.failIf(der.hasOnlyInts()) # One single-byte integer (zero) der.append(0) self.assertEquals(der.encode(), b('0\x03\x02\x01\x00')) self.failUnless(der.hasOnlyInts()) # Invariant self.assertEquals(der.encode(), b('0\x03\x02\x01\x00')) def testEncode2(self): # One single-byte integer (non-zero) der = DerSequence() der.append(127) self.assertEquals(der.encode(), b('0\x03\x02\x01\x7f')) # Indexing der[0] = 1 self.assertEquals(len(der),1) self.assertEquals(der[0],1) self.assertEquals(der[-1],1) self.assertEquals(der.encode(), b('0\x03\x02\x01\x01')) # der[:] = [1] self.assertEquals(len(der),1) self.assertEquals(der[0],1) self.assertEquals(der.encode(), b('0\x03\x02\x01\x01')) def testEncode3(self): # One multi-byte integer (non-zero) der = DerSequence() der.append(0x180L) self.assertEquals(der.encode(), b('0\x04\x02\x02\x01\x80')) def testEncode4(self): # One very long integer der = DerSequence() der.append(2**2048) self.assertEquals(der.encode(), b('0\x82\x01\x05')+ b('\x02\x82\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00')) def testEncode5(self): # One single-byte integer (looks negative) der = DerSequence() der.append(0xFFL) self.assertEquals(der.encode(), b('0\x04\x02\x02\x00\xff')) def testEncode6(self): # Two integers der = DerSequence() der.append(0x180L) der.append(0xFFL) self.assertEquals(der.encode(), b('0\x08\x02\x02\x01\x80\x02\x02\x00\xff')) self.failUnless(der.hasOnlyInts()) # der.append(0x01) der[1:] = [9,8] self.assertEquals(len(der),3) self.assertEqual(der[1:],[9,8]) self.assertEqual(der[1:-1],[9]) self.assertEquals(der.encode(), b('0\x0A\x02\x02\x01\x80\x02\x01\x09\x02\x01\x08')) def testEncode6(self): # One integer and another type (no matter what it is) der = DerSequence() der.append(0x180L) der.append(b('\x00\x02\x00\x00')) self.assertEquals(der.encode(), b('0\x08\x02\x02\x01\x80\x00\x02\x00\x00')) self.failIf(der.hasOnlyInts()) #### def testDecode1(self): # Empty sequence der = DerSequence() der.decode(b('0\x00')) self.assertEquals(len(der),0) # One single-byte integer (zero) der.decode(b('0\x03\x02\x01\x00')) self.assertEquals(len(der),1) self.assertEquals(der[0],0) # Invariant der.decode(b('0\x03\x02\x01\x00')) self.assertEquals(len(der),1) self.assertEquals(der[0],0) def testDecode2(self): # One single-byte integer (non-zero) der = DerSequence() der.decode(b('0\x03\x02\x01\x7f')) self.assertEquals(len(der),1) self.assertEquals(der[0],127) def testDecode3(self): # One multi-byte integer (non-zero) der = DerSequence() der.decode(b('0\x04\x02\x02\x01\x80')) self.assertEquals(len(der),1) self.assertEquals(der[0],0x180L) def testDecode4(self): # One very long integer der = DerSequence() der.decode(b('0\x82\x01\x05')+ b('\x02\x82\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ b('\x00\x00\x00\x00\x00\x00\x00\x00\x00')) self.assertEquals(len(der),1) self.assertEquals(der[0],2**2048) def testDecode5(self): # One single-byte integer (looks negative) der = DerSequence() der.decode(b('0\x04\x02\x02\x00\xff')) self.assertEquals(len(der),1) self.assertEquals(der[0],0xFFL) def testDecode6(self): # Two integers der = DerSequence() der.decode(b('0\x08\x02\x02\x01\x80\x02\x02\x00\xff')) self.assertEquals(len(der),2) self.assertEquals(der[0],0x180L) self.assertEquals(der[1],0xFFL) def testDecode7(self): # One integer and 2 other types der = DerSequence() der.decode(b('0\x0A\x02\x02\x01\x80\x24\x02\xb6\x63\x12\x00')) self.assertEquals(len(der),3) self.assertEquals(der[0],0x180L) self.assertEquals(der[1],b('\x24\x02\xb6\x63')) self.assertEquals(der[2],b('\x12\x00')) def testDecode8(self): # Only 2 other types der = DerSequence() der.decode(b('0\x06\x24\x02\xb6\x63\x12\x00')) self.assertEquals(len(der),2) self.assertEquals(der[0],b('\x24\x02\xb6\x63')) self.assertEquals(der[1],b('\x12\x00')) def testErrDecode1(self): # Not a sequence der = DerSequence() self.assertRaises(ValueError, der.decode, b('')) self.assertRaises(ValueError, der.decode, b('\x00')) self.assertRaises(ValueError, der.decode, b('\x30')) def testErrDecode2(self): # Wrong payload type der = DerSequence() self.assertRaises(ValueError, der.decode, b('\x30\x00\x00'), True) def testErrDecode3(self): # Wrong length format der = DerSequence() self.assertRaises(ValueError, der.decode, b('\x30\x04\x02\x01\x01\x00')) self.assertRaises(ValueError, der.decode, b('\x30\x81\x03\x02\x01\x01')) self.assertRaises(ValueError, der.decode, b('\x30\x04\x02\x81\x01\x01')) def testErrDecode4(self): # Wrong integer format der = DerSequence() # Multi-byte encoding for zero #self.assertRaises(ValueError, der.decode, '\x30\x04\x02\x02\x00\x00') # Negative integer self.assertRaises(ValueError, der.decode, b('\x30\x04\x02\x01\xFF')) def get_tests(config={}): from Crypto.SelfTest.st_common import list_test_cases listTests = [] listTests += list_test_cases(DerObjectTests) listTests += list_test_cases(DerSequenceTests) return listTests if __name__ == '__main__': suite = lambda: unittest.TestSuite(get_tests()) unittest.main(defaultTest='suite') # vim:set ts=4 sw=4 sts=4 expandtab: