[Cryptech-Commits] [sw/pkcs11] 05/07: Unit tests for init, session, and login functions.

git at cryptech.is git at cryptech.is
Mon Sep 21 23:26:11 UTC 2015


This is an automated email from the git hooks/post-receive script.

sra at hactrn.net pushed a commit to branch ecdsa
in repository sw/pkcs11.

commit f723a3b05eb960a2c0e4fe5e86c8dde91a425acf
Author: Rob Austein <sra at hactrn.net>
Date:   Mon Sep 21 16:40:34 2015 -0400

    Unit tests for init, session, and login functions.
---
 GNUmakefile      |  4 +--
 pkcs11.c         | 11 +++++++
 py11/__init__.py | 11 +++----
 unit_tests.py    | 90 +++++++++++++++++++++++++++-----------------------------
 4 files changed, 63 insertions(+), 53 deletions(-)

diff --git a/GNUmakefile b/GNUmakefile
index 89f713c..77daebd 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -39,7 +39,7 @@ LIBHAL_DIR   = ../libhal
 LIBTFM_DIR   = ../thirdparty/libtfm
 SQLITE3_DIR  = ../thirdparty/sqlite3
 
-CFLAGS	:= -g3 -fPIC -Wall -std=c99 -I${LIBHAL_DIR} -I${SQLITE3_DIR}
+CFLAGS	:= -g3 -fPIC -Wall -std=c99 -I${LIBHAL_DIR} -I${SQLITE3_DIR} -DDEBUG_PKCS11=0
 SOFLAGS := -Wl,-Bsymbolic-functions -Wl,-Bsymbolic -Wl,-z,noexecstack
 LIBS	:= ${LIBHAL_DIR}/libhal.a ${LIBTFM_DIR}/libtfm.a ${SQLITE3_DIR}/libsqlite3.a
 
@@ -90,7 +90,7 @@ tags: TAGS
 TAGS: *.[ch]
 	etags $^
 
-test:
+test: all
 	sudo python unit_tests.py
 
 # Kudge for testing, gussy this up if we decide to keep it
diff --git a/pkcs11.c b/pkcs11.c
index 93a5f36..eef1aec 100644
--- a/pkcs11.c
+++ b/pkcs11.c
@@ -1593,6 +1593,10 @@ static CK_RV p11_session_delete(const CK_SESSION_HANDLE session_handle)
   p11_sessions = session->link;
   p11_session_free(session);
 
+  /* Deleting last session also logs us out */
+  if (p11_sessions == NULL)
+    logged_in_as = not_logged_in;
+
  fail:
   sqlite3_finalize(q);
   return rv;
@@ -1621,6 +1625,8 @@ static CK_RV p11_session_delete_all(void)
     p11_session_free(session);
   }
 
+  logged_in_as = not_logged_in;
+
  fail:
   return rv;
 }
@@ -2696,6 +2702,11 @@ CK_RV C_Finalize(CK_VOID_PTR pReserved)
   rv =  mutex_unlock(p11_global_mutex);
   (void) mutex_destroy(p11_global_mutex);
   p11_global_mutex = NULL;
+
+#if USE_POSIX
+  initialized_pid = 0;
+#endif
+
   return rv;
 
  fail:
diff --git a/py11/__init__.py b/py11/__init__.py
index d800ab7..ec51d19 100644
--- a/py11/__init__.py
+++ b/py11/__init__.py
@@ -83,10 +83,10 @@ class PKCS11 (object):
       self._C_Initialize_args = None
       self.so.C_Initialize(None)
     else:
-      create_mutex  = cast(None, CK_CREATEMUTEX)  if create_mutex  is None else CK_CREATEMUTEX(create_mutex)
-      destroy_mutex = cast(None, CK_DESTROYMUTEX) if destroy_mutex is None else CK_DESTROYMUTEX(destroy_mutex)
-      lock_mutex    = cast(None, CK_LOCKMUTEX)    if lock_mutex    is None else CK_LOCKMUTEX(lock_mutex)
-      unlock_mutex  = cast(None, CK_UNLOCKMUTEX)  if unlock_mutex  is None else CK_UNLOCKMUTEX(unlock_mutex)
+      create_mutex  = CK_CREATEMUTEX()  if create_mutex  is None else CK_CREATEMUTEX(create_mutex)
+      destroy_mutex = CK_DESTROYMUTEX() if destroy_mutex is None else CK_DESTROYMUTEX(destroy_mutex)
+      lock_mutex    = CK_LOCKMUTEX()    if lock_mutex    is None else CK_LOCKMUTEX(lock_mutex)
+      unlock_mutex  = CK_UNLOCKMUTEX()  if unlock_mutex  is None else CK_UNLOCKMUTEX(unlock_mutex)
       self._C_Initialize_args = CK_C_INITIALIZE_ARGS(create_mutex, destroy_mutex, lock_mutex, unlock_mutex, flags, None)
       self.so.C_Initialize(cast(byref(self._C_Initialize_args), CK_VOID_PTR))
 
@@ -105,7 +105,8 @@ class PKCS11 (object):
     self.so.C_GetTokenInfo(slot_id, byref(token_info))
     return token_info
 
-  def C_OpenSession(self, slot, flags = CKF_SERIAL_SESSION | CKF_RW_SESSION, application = None, notify = CK_NOTIFY()):
+  def C_OpenSession(self, slot, flags = CKF_RW_SESSION, application = None, notify = CK_NOTIFY()):
+    flags |= CKF_SERIAL_SESSION
     handle = CK_SESSION_HANDLE()
     self.so.C_OpenSession(slot, flags, application, notify, byref(handle))
     return handle.value
diff --git a/unit_tests.py b/unit_tests.py
index a59b731..2e4dc5d 100644
--- a/unit_tests.py
+++ b/unit_tests.py
@@ -8,6 +8,10 @@ from py11.mutex import MutexDB
 
 p11 = None
 
+so_pin    = "fnord"
+user_pin  = "fnord"
+only_slot = 0
+
 class TestInit(unittest.TestCase):
 
   def test_no_lock(self):
@@ -29,63 +33,55 @@ class TestInit(unittest.TestCase):
 
 class TestDevice(unittest.TestCase):
 
-  def test_slots(self):
-    slots = p11.C_GetSlotList()
-    self.assertIsInstance(slots, (list, tuple))
-    self.assertEqual(len(slots), 1)
-    self.assertIsInstance(slots[0], (int, long))
-
- at unittest.skip("This was just an example")
-class Test1(unittest.TestCase):
-
-  @classmethod
-  def setUpClass(cls):
-    pass #print "Class-wide setup"
-
-  @classmethod
-  def tearDownClass(cls):
-    pass #print "Class-wide teardown"
-
-  def setUp(self):
-    pass #print "Per-test setup"
-
-  def tearDown(self):
-    pass #print "Per-test teardown"
-
-  def test_one(self):
-    pass #print "Test one"
-    self.assertTrue(True)
-
-  def test_two(self):
-    pass #print "Test two"
-    self.assertTrue(True)
-
- at unittest.skip("This was also just an example")
-class Test2(unittest.TestCase):
-
   @classmethod
   def setUpClass(cls):
-    pass #print "Class-wide setup"
+    p11.C_Initialize()
 
   @classmethod
   def tearDownClass(cls):
-    pass #print "Class-wide teardown"
-
-  def setUp(self):
-    pass #print "Per-test setup"
+    p11.C_Finalize()
 
   def tearDown(self):
-    pass #print "Per-test teardown"
+    p11.C_CloseAllSessions(only_slot)
 
-  def test_three(self):
-    pass #print "Test three"
-    self.assertTrue(True)
+  def test_slots(self):
+    self.assertEqual(p11.C_GetSlotList(), [only_slot])
+
+  def test_serial_sessions(self):
+    rw_session = p11.C_OpenSession(only_slot, CKF_RW_SESSION | CKF_SERIAL_SESSION)
+    ro_session = p11.C_OpenSession(only_slot, CKF_SERIAL_SESSION)
+
+  def test_parallel_sessions(self):
+    # Cooked API doesn't allow the user to make this mistake, so we
+    # have to use the raw API to test it.
+    from ctypes import byref
+    handle = CK_SESSION_HANDLE()
+    notify = CK_NOTIFY()
+    with self.assertRaises(CKR_SESSION_PARALLEL_NOT_SUPPORTED):
+      p11.so.C_OpenSession(only_slot, CKF_RW_SESSION, None, notify, byref(handle))
+    with self.assertRaises(CKR_SESSION_PARALLEL_NOT_SUPPORTED):
+      p11.so.C_OpenSession(only_slot, 0,              None, notify, byref(handle))
+
+  def test_login_user(self):
+    rw_session = p11.C_OpenSession(only_slot, CKF_RW_SESSION | CKF_SERIAL_SESSION)
+    ro_session = p11.C_OpenSession(only_slot, CKF_SERIAL_SESSION)
+    p11.C_Login(ro_session, CKU_USER, user_pin)
+    p11.C_Logout(ro_session)
+
+  def test_login_so(self):
+    rw_session = p11.C_OpenSession(only_slot, CKF_RW_SESSION | CKF_SERIAL_SESSION)
+    ro_session = p11.C_OpenSession(only_slot, CKF_SERIAL_SESSION)
+    self.assertRaises(CKR_SESSION_READ_ONLY_EXISTS, p11.C_Login, ro_session, CKU_SO, user_pin)
+    p11.C_CloseSession(ro_session)
+    p11.C_Login(rw_session, CKU_SO, user_pin)
+    self.assertRaises(CKR_SESSION_READ_WRITE_SO_EXISTS, p11.C_OpenSession, only_slot, CKF_SERIAL_SESSION)
+    p11.C_Logout(rw_session)
 
 def setUpModule():
   from os import environ
   from os.path import abspath
   global p11
-  p11 = PKCS11()
+  p11 = PKCS11("./libpkcs11.so")
   environ["PKCS11_DATABASE"] = abspath("unit_tests.db")
   delete_db()
   set_pin()
@@ -95,15 +91,17 @@ def tearDownModule():
 
 def delete_db():
   from os import environ, unlink
+  print "Deleting database", environ["PKCS11_DATABASE"]
   try:
     unlink(environ["PKCS11_DATABASE"])
   except OSError, e:
     if e.errno != 2:
       raise
 
-def set_pin(user_pin = "fnord", so_pin = "fnord"):
+def set_pin():
   from subprocess import Popen, PIPE
-  Popen(("./p11util", "-sup"), stdin = PIPE).communicate("fnord\nfnord\n")
+  print "Creating database and setting PINs"
+  Popen(("./p11util", "-sup"), stdin = PIPE).communicate("%s\n%s\n" % (so_pin, user_pin))
 
 if __name__ == "__main__":
   unittest.main(verbosity = 2)



More information about the Commits mailing list