]> wagner.pp.ru Git - oss/ctypescrypto.git/commitdiff
Added first test file - for oid module
authorVictor Wagner <wagner@atlas-card.ru>
Thu, 5 Jun 2014 07:59:23 +0000 (11:59 +0400)
committerVictor Wagner <wagner@atlas-card.ru>
Thu, 5 Jun 2014 07:59:23 +0000 (11:59 +0400)
MANIFEST.in [new file with mode: 0644]
ctypescrypto/oid.py
setup.py [new file with mode: 0644]
tests/testoids.py [new file with mode: 0644]

diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644 (file)
index 0000000..16b52e4
--- /dev/null
@@ -0,0 +1 @@
+include tests/*.py
index 81bea92a05f59cf583dff60df9607a3cdccf5b39..9852043e0b936cf8e5b9dc5b0c25cbbed2011734 100644 (file)
@@ -1,29 +1,97 @@
 """    
- Interface to OpenSSL object identifier database
+ Interface to OpenSSL object identifier database.
+ It is primarily intended to deal with OIDs which are compiled into the
+ database or defined in the openssl configuration files.
+
+ But see create() function
+
 """
 from ctypescrypto import libcrypto
+from ctypes import c_char_p, c_void_p, c_int, create_string_buffer
 class Oid:
+       """
+               Represents an OID. It can be consturucted by textual
+               representation like Oid("commonName") or Oid("CN"),
+               dotted-decimal Oid("1.2.3.4") or using OpenSSL numeric
+               identifer (NID), which is typically returned or required by 
+               OpenSSL API functions. If object is consturcted from textual
+               representation which is not present in the database, it fails
+               with ValueError
+
+               attribute nid - contains object nid.
+
+
+       """
+
        def __init__(self,value):
+               " Object constuctor. Accepts string or integer"
                if type(value) == type(""):
                        self.nid=libcrypto.OBJ_txt2nid(value)
                        if self.nid==0:
-                               raise LibCryptoError("Cannot find object %s in the
-                               database"%(value))
+                               raise ValueError("Cannot find object %s in the database"%(value))
                elif type(value) == type(0):
+                       cn=libcrypto.OBJ_nid2sn(value)
+                       if cn is None:
+                               raise ValueError("No such nid %d in the database"%(value))
                        self.nid=value
                else:
                        raise TypeError("Cannot convert this type to object identifier")
+       def __hash__(self):
+               " Returns NID "
+               return self.nid
        def __cmp__(self,other):
+               " Compares NIDs of two objects "
                return self.nid-other.nid
        def __str__(self):
+               " Default string representation of Oid is dotted-decimal"
                return self.dotted()
-       def shorttname(self):
+       def __repr__(self):
+               return "Oid('%s')"%(self.dotted())
+       def shortname(self):
+               " Returns short name if any "
                return libcrypto.OBJ_nid2sn(self.nid)
        def longname(self):
+               " Returns logn name if any "
                return  libcrypto.OBJ_nid2ln(self.nid)
-       def dotted(self)
+       def dotted(self):
+               " Returns dotted-decimal reperesntation "
                obj=libcrypto.OBJ_nid2obj(self.nid)
                buf=create_string_buffer(256)
                libcrypto.OBJ_obj2txt(buf,256,obj,1)
                return buf.value
 
+def create(dotted,shortname,longname):
+       """
+               Creates new OID in the database
+
+               @param dotted - dotted-decimal representation of new OID
+               @param shortname - short name for new OID
+               @param longname - long name for new OID
+
+               @returns Oid object corresponding to new OID
+               
+               This function should be used with exreme care. Whenever
+               possible, it is better to add new OIDs via OpenSSL configuration
+               file
+
+               Results of calling this function twice for same OIDor for
+               Oid alredy in database are undefined
+       """
+       nid=libcrypto.OBJ_create(dotted,shortname,longname)
+       if nid == 0:
+               raise LibCryptoError("Problem adding new OID to the  database")
+       return Oid(nid)
+
+def cleanup():
+       """
+               Removes all the objects, dynamically added by current
+               application from database.
+       """
+       libcrypto.OBJ_cleanup()
+
+libcrypto.OBJ_nid2sn.restype=c_char_p
+libcrypto.OBJ_nid2ln.restype=c_char_p
+libcrypto.OBJ_nid2obj.restype=c_void_p
+libcrypto.OBJ_obj2txt.argtypes=(c_char_p,c_int,c_void_p,c_int)
+libcrypto.OBJ_txt2nid.argtupes=(c_char_p,)
+libcrypto.OBJ_create.argtypes=(c_char_p,c_char_p,c_char_p)
diff --git a/setup.py b/setup.py
new file mode 100644 (file)
index 0000000..b6f1b2b
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,44 @@
+from distutils.core import setup
+import distutils.cmd
+import sys,os
+
+class MyTests(distutils.cmd.Command):
+       user_options=[]
+       def initialize_options(self):
+               pass
+       def finalize_options(self):
+               pass
+       def run(self):
+               sys.path.insert(0,os.getcwd())
+               import unittest
+               result=unittest.TextTestResult(sys.stdout,True,True)
+               suite= unittest.defaultTestLoader.discover("./tests")
+               print "Discovered %d test cases"%suite.countTestCases()
+               result.buffer=True
+               suite.run(result)
+               print ""
+               if not result.wasSuccessful():
+                       if len(result.errors):
+                               print "============ Errors disovered ================="
+                               for r in result.errors:
+                                       print r[0],":",r[1]
+                       
+                       if len(result.failures):
+                               print "============ Failures disovered ================="
+                               for r in result.failures:
+                                       print r[0],":",r[1]
+                       sys.exit(1)
+               else:
+                       print "All tests successful"
+
+setup(
+       name="ctypescrypto"
+       version="0.2.0"
+       description="CTypes-based interface for some OpenSSL libcrypto features"
+       author="Victor Wagner",
+       author_email="vitus@wagner.pp.ru",
+       url="https://github.com/vbwagner/ctypescrypto",
+       packages=["ctypescrypto"],
+       cmdlass={"test":MyTests}
+)
+
diff --git a/tests/testoids.py b/tests/testoids.py
new file mode 100644 (file)
index 0000000..f324f7e
--- /dev/null
@@ -0,0 +1,69 @@
+from ctypescrypto.oid import Oid,create,cleanup
+import unittest
+
+class TestStandard(unittest.TestCase):
+       def test_cn(self):
+               o=Oid("2.5.4.3")
+               self.assertEqual(repr(o),"Oid('2.5.4.3')")
+               self.assertEqual(o.dotted(),"2.5.4.3")
+               self.assertEqual(str(o),"2.5.4.3")
+               self.assertEqual(o.shortname(),"CN")
+               self.assertEqual(o.longname(),"commonName")
+       def test_getnid(self):
+               o=Oid("2.5.4.3")
+               x=Oid("CN")
+               self.assertEqual(o.nid,x.nid)
+               self.assertEqual(o,x)
+               self.assertEqual(hash(o),hash(x))
+
+       def test_cons2(self):
+               o=Oid("2.5.4.3")
+               x=Oid("commonName")
+               self.assertEqual(o.nid,x.nid)
+       def test_bynid(self):
+               o=Oid("2.5.4.3")
+               x=Oid(o.nid)
+               self.assertEqual(o.nid,x.nid)
+       def test_wrongoid(self):
+               with self.assertRaises(ValueError):
+                       o=Oid("1.2.3.4.5.6.7.8.10.111.1111")
+       def test_wrongname(self):
+               with self.assertRaises(ValueError):
+                       o=Oid("No such oid in the database")
+       def test_wrongtype(self):
+               with self.assertRaises(TypeError):
+                       o=Oid([2,5,3,4])
+
+class TestCustom(unittest.TestCase):
+       def testCreate(self):
+               d='1.2.643.100.3'
+               sn="SNILS"
+               long_name="Russian Pension security number"
+               o=create(d,sn,long_name)
+               self.assertEqual(str(o),d)
+               self.assertEqual(o.shortname(),sn)
+               self.assertEqual(o.longname(),long_name)
+       def testLookup(self):
+               d='1.2.643.100.3'
+               sn="SNILS"
+               long_name="Russian Pension security number"
+               o=create(d,sn,long_name)
+               x=Oid(sn)
+               self.assertEqual(o,x)
+       def testCleanup(self):
+               d='1.2.643.100.3'
+               sn="SNILS"
+               long_name="Russian Pension security number"
+               o=create(d,sn,long_name)
+               cleanup()
+               with self.assertRaises(ValueError):
+                       x=Oid(sn)
+       def tearDown(self):
+               # Always call cleanup before next test
+               cleanup()
+       
+
+
+
+if __name__ == '__main__':
+       unittest.main()